concat()#

relationalai.std.aggregates
#concat(string: Producer, sep: str = "", per: list[Producer] = []) -> Expression

Concatenates distinct string values produced by a Producer object, separated by the sep string. Pass a list of Producer objects to the optional per parameter to group values and compute the concatenation per group. Must be called in a rule or query context.

Parameters#

NameTypeDescription
stringProducerA Producer object producing string values to concatenate.
sepstrSeparator string to insert between concatenated values. (Default: "")
perlist[Producer]An optional list of Producer objects used to group arguments. (Default: [])

Returns#

An Expression object.

Example#

Use concat() to concatenate distinct string values produced by a Producer object:

#import relationalai as rai
from relationalai.std import aggregates, alias


# =====
# SETUP
# =====

model = rai.Model("MyModel")
Person = model.Type("Person")

with model.rule():
    joe = Person.add(name="Joe")
    jane = Person.add(name="Jane")
    john = Person.add(name="John")
    joe.hobbies.extend(["hiking", "skating"])
    jane.hobbies.extend(["skating", "reading"])
    john.hobbies.extend(["fishing"])


# =======
# EXAMPLE
# =======

with model.query() as select:
    person = Person()
    # Concatenate distinct hobby values.
    hobbies = aggregates.concat(person.hobbies, sep=", ")
    response = select(alias(hobbies, "hobby_list"))

print(response.results)
#                           hobby_list
# 0  fishing, hiking, reading, skating

The Producer passed to concat() must only produce string values. If any non-string values are produced, you may encounter unexpected empty results:

#with model.rule():
    joe.hobbies.extend([1, 2.34])  # Add some numbers to Joe's hobbies.

with model.query() as select:
    person = Person(name="Joe")
    hobbies = aggregates.concat(person.hobbies, sep=", ")
    response = select(alias(hobbies, "hobby_list"))

print(response.results)
# Empty DataFrame
# Columns: []
# Index: []

To ensure that only string values are produced, you can use the String() filter function to filter out non-string values:

#
from relationalai.std.strings import String

with model.query() as select:
    person = Person(name="Joe")
    String(person.hobbies)  # Filter out non-string values.
    hobbies = aggregates.concat(person.hobbies, sep=", ")
    response = select(alias(hobbies, "hobby_list"))

print(response.results)
#         hobby_list
# 0  hiking, skating

To group values and concatenate within each group, pass a list of one or more Producer objects to the optional per keyword argument. In the following example, the person object is passed to per to concatenate a person’s friends’ names:

## Set a multi-valued friends property for each person.
with model.rule():
    joe = Person(name="Joe")
    jane = Person(name="Jane")
    john = Person(name="John")
    joe.friends.extend([jane, john])
    jane.friends.extend([joe])
    john.friends.extend([joe])

with model.query() as select:
    person = Person()
    # Filter out non-string values from person.friends.hobbies.
    String(person.friends.hobbies)
    # Concatenate the all hobbies each person's friends.
    friends_hobbies = aggregates.concat(person.friends.hobbies, sep=", ", per=[person])
    response = select(person.name, alias(friends_hobbies, "friends_hobbies"))

print(response.results)
#    name            friends_hobbies
# 0  Jane            hiking, skating
# 1   Joe  fishing, reading, skating
# 2  John            hiking, skating

See Also#