[英]Build rethinkdb query dynamically - python
I'm trying to build a rethinkdb query server-side, dynamically. 我正在尝试动态构建服务器端rethinkdb查询。 The end goal is to have queries that are structured approximately like this (in javascript):
最终目标是使查询的结构大致如下所示(在javascript中):
r.db('test').table('data')
.filter(function (row) {
return row('subgroup').eq('x').or(row('subgroup').eq('y'))
.and(
.row('metric_id').eq('a')
.or(row('metric_id).eq('b')
.or(row('metric_id').eq('c'))
})
I need to pass in a set of keys, each with a set of acceptable values. 我需要传递一组键,每个键都有一组可接受的值。 For the above example, I'd pass in
对于上面的示例,我将传递
{
'subgroup': ['x', 'y'],
'metric_id': ['a', 'b', 'c']
}
The query should return all records for which subgroup
is x
OR y
AND metric_id
is a
OR b
OR c
. 查询应返回所有的记录进行
subgroup
是x
或y
和metric_id
是a
OR b
或c
。
I'm struggling with the correct way to do this. 我正在努力做到这一点的正确方法。 See one attempt below:
请参阅以下尝试:
def parse_filters(cls, filters):
def rethink_filter(data):
result = r.expr(True) # initialize filter function
for key in filters:
or_statements = []
for value in filters[key]:
f = {}
f[key] = value
or_statements.append(r.expr(f)) # build a list of
result = result.and_(r.or_(r.expr(or_statements)))
if not result:
break
return result
return rethink_filter
With the input of 随着输入
{
'entity_id': ['a', 'b'],
'metric_id': ['x']
}
rethink_filter
gives the query: rethink_filter
给出查询:
r.and_(r.and_(True, r.or_([{'entity_id': 'a'}, {'entity_id': 'b'}])), r.or_([{'metric_id': 'x'}]))
which looks like it ought to give the results I'm after, but it returns all items in the table, regardless of entity_id
or metric_id
. 看起来应该给出我想要的结果,但是它返回表中的所有项目,而不管
entity_id
还是metric_id
。
Where am I going wrong? 我要去哪里错了?
r.or
can be used as an infix operator, or all of the arguments can be provided as parameters . r.or
可以用作中缀运算符,或者所有参数都可以作为parameter提供。 You are passing in only a single parameter: an array. 您只传递一个参数:数组。
Since an array always evaluated to True, this query: 由于数组始终求值为True,因此此查询:
r.and_(r.and_(True, r.or_([{'entity_id': 'a'}, {'entity_id': 'b'}])), r.or_([{'metric_id': 'x'}]))
effectively becomes: 有效地变为:
r.and_(r.and_(True, r.or_(True)), r.or_(True))
Which I hope you can see will evaluate to True
for every record. 我希望您能看到的每条记录都将评估为
True
。
When you need to pass an array to a function in RethinkDB that expects parameters, you can use r.args
. 当您需要将数组传递给RethinkDB中需要参数的函数时,可以使用
r.args
。
You will also not be able to use the dictionary shorthand inside of an r.or
function. 您也将无法在
r.or
函数内部使用字典速记。 That is, instead of { 'entity_id' : 'a' }
you will need to translate those into document['entity_id'] == 'a'
I believe. 也就是说,您需要将它们翻译成
document['entity_id'] == 'a'
,而不是{ 'entity_id' : 'a' }
。 You can get access to the document through a lambda function, see the examples on the filter documentation . 您可以通过lambda函数访问文档,请参阅过滤器文档上的示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.