linkyndy
linkyndy

Reputation: 17900

Combine multiple filters in RethinkDB and merge results from each filter with a ranking field

Okay, say I have the following list:

[(('a', 'b', 'c'), 1), (('a', 'c'), 2), (('b'), 3)]

This list is composed of 3 tuples, each having 2 elements: a filter and a ranking. I would like to create a ReQL query, dynamically, that filters a table for each filter from the above list (using has_fields), and then adds a new field, ranking: [n], when n is the ranking from the above list.

To get the idea, here's how I would do it with multiple queries:

for filters, ranking in list_:
    r.table(...).filter(lambda doc: doc.has_fields(*filters)).map(lambda doc: doc.merge({'ranking': ranking})).run(...)

I would like to merge the above queries into a single one, to minimize interaction with the database. Appreciate any help on this.

Upvotes: 1

Views: 567

Answers (1)

Etienne Laurin
Etienne Laurin

Reputation: 7184

You can

  • Use concatMap for combining your queries
  • Replace python splats such as *filter with r.args(filter)
  • Simplify .filter(lambda x: x.has_fields(...)) to just .has_fields(...)
  • Same for map and merge

The code would look something like this:

 (r.expr(list_)
   .concatMap(lambda filts_rank:
      r.table(...)
       .has_fields(r.args(filts_rank[0]))
       .merge({'ranking': filts_rank[1]}))
 ).run(...)

Note that if you have duplicate keys in list_, some documents from the table may be returned multiple times, each with a different ranking.

Upvotes: 1

Related Questions