动态构建rethinkdb查询 - python

时间:2017-09-21 12:16:33

标签: python rethinkdb

我正在尝试动态地构建rethinkdb查询服务器端。最终目标是让查询的结构大致类似于此(在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'))
})

我需要传递一组键,每组键都有一组可接受的值。对于上面的例子,我会传入

{
  'subgroup': ['x', 'y'],
  'metric_id': ['a', 'b', 'c']
}

查询应返回subgroupxymetric_idab或{{1}的所有记录}}

我正在努力做正确的方法。请参阅以下一项尝试:

c

输入

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

{ 'entity_id': ['a', 'b'], 'metric_id': ['x'] } 提供查询:

rethink_filter

看起来它应该给出我之后的结果,但它会返回表格中的所有项目,无论r.and_(r.and_(True, r.or_([{'entity_id': 'a'}, {'entity_id': 'b'}])), r.or_([{'metric_id': 'x'}])) 还是entity_id

我哪里错了?

1 个答案:

答案 0 :(得分:0)

r.or可以用作中缀运算符,或者所有参数都可以作为参数提供。您只传入一个参数:一个数组。

由于数组总是被评估为True,因此该查询:

r.and_(r.and_(True, r.or_([{'entity_id': 'a'}, {'entity_id': 'b'}])), r.or_([{'metric_id': 'x'}]))

有效地成为:

r.and_(r.and_(True, r.or_(True)), r.or_(True))

我希望你能看到我会为每条记录评估True

当您需要将数组传递给RethinkDB中需要参数的函数时,可以使用r.args

您也无法在r.or函数内使用字典速记。也就是说,我需要将{ 'entity_id' : 'a' }转换为document['entity_id'] == 'a'而不是data: Data。您可以通过lambda函数访问文档,请参阅filter documentation上的示例。