2

I am trying to filter the array object inside a table. Here is a case where I have filtered and it works perfectly.

tags = ["school", "hollywood"]
tagsLambda =  lambda post: (post["tags"].contains(tags[0])) | (post["tags"].contains(tags[1]))
d = r.db("test").table("posts").filter(
    tagsLambda
).run()

But, My question is I am doing the lambda operation manually, instead I want tagsLambda to filter all the tags. How do I do it?

iraycd
  • 892
  • 1
  • 8
  • 23

2 Answers2

3

I think you should be able to do something like this:

tags = ["school", "hollywood"]
r.db("test").table("posts").filter(
  lambda post: post["tags"].contains(lambda tag:
    r.expr(tags).contains(tag)
  )
).run(conn)

See http://rethinkdb.com/api/python/contains/

gunn
  • 8,999
  • 2
  • 24
  • 24
1
tags = ["school", "hollywood"]
tagsLambda =  lambda post: ( 
eval('|'.join(
           [r'(post["tags"].contains("' + tag + '"))' for tag in tags]
    ))
)
d = r.db("test").table("posts").filter(tagsLambda).run()  

[ r'post["tags"].contains("' + tag + '")' for tag in tags ] is a list comprehension. It builds a list of strings like (post["tags"].contains("school")) for each tag in tags. The '|'.join operation builds a string from the list of strings with '|' in between like (post["tags"].contains("school")) | (post["tags"].contains("hollywood")). eval evaluates the whole string.

The above code can be simplified using reduce as

tags = ["school", "hollywood"]
tagsLambda =  lambda post:
    reduce(lambda x,y: x | y, [ post["tags"].contains(tag) for tag in tags])

d = r.db("test").table("posts").filter(tagsLambda).run()  

For Python 3, 'functools' has to be imported to use reduce and replace reduce with functools.reduce.

The second lambda can be replaced with a function.

import operator as op
reduce(op.or_, [ post["tags"].contains(tag) for tag in tags])  

User generators for better result.

reduce(op.or_, ( post["tags"].contains(tag) for tag in tags))  
Nizam Mohamed
  • 8,751
  • 24
  • 32
  • Dude, this won't work. It should be an `or` operator that is for sure. – iraycd Feb 09 '15 at 12:49
  • Could you provide an explanation on what this code actually does? Thanks – Paco Feb 09 '15 at 15:06
  • 1
    @iraycd why you need '|'? how can you filter by a single tag? I think '|' is only needed if you want to filter by multiple tags – Nizam Mohamed Feb 09 '15 at 17:05
  • @NizamMohamed That is what I really wanted. Your solution is great. I guess your solution will even work with `&` operations. :) – iraycd Feb 09 '15 at 19:18