Question

Thanks to the answer here, I manged to get all the rows that contain a given string as a substring of a specific field's value by:

r.db('my_db').table('my_table').filter(lambda row: row['some_key'].match(".\*some_given_string.\*"))

What if I want to have a similar result, but this time, "some_key" is a list of strings instead of a single string? Say for the following table:

[{"name": "row1", "some_key": ["str1", "str2"]}, {"name": "row2", "some_key": ["str3", "blah"]}, {"name": "row3", "some_key": ["blah", "blahblah"]}]

I want to look for ".*tr.*" and get the first two rows only because the last one has a list under "some_key" that doesn't contain "tr" in none of its strings.

How can I do that with rethinkdb?

Was it helpful?

Solution

On a stream/array you can use contains that behaves like a any operator when given a function.

r.db('my_db').table('my_table').filter(lambda row:      
    row["some_key"].contains(lambda key:
        key.match(".\*some_given_string.\*")
    )
)

OTHER TIPS

Short answer:

def has_match(row, regex):
    return row['some_key']
           .map(lambda x: x.match(regex))
           .reduce(lambda x,y: x | y)


my_table.filter(lambda row: has_match(row, ".*tr.*"))

Longer answer:

match is a method that you can call on a string. In general in ReQL when you have an array of X and a function you want to apply to each element of the array you want to use the map command. For example if you run:

r.expr(["foo", "boo", "bar"]).map(lambda x: x.match(".\*oo"))

you'll get back:

[True, True, False]

I'm a bit unclear from your question but I think what you want here is to get all the documents in which ANY of these strings matches regex. To see if any of them match you need to reduce the booleans together using or so it would be:

list_of_bools.reduce(lambda x,y: x | y)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top