简体   繁体   English

动态构建rethinkdb查询-python

[英]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 . 查询应返回所有的记录进行subgroupxymetric_ida OR bc

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM