2017-09-21 61 views
0

我正试图动态地生成rethinkdb查询服务器端。的最终目标是具有被构造大致像这样(在JavaScript)查询:动态地生成rethinkdb查询 - python

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_idabc

我正在努力以正确的方式来做到这一点。见下面一个尝试:

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_idmetric_id

我哪里错了?

+0

对于什么是值得的,虽然RethinkDB可以做这些查询,但可能难以构建/维护它们,并且难以针对索引级性能优化它们。因此,将Elasticsearch等技术与数据库集成可能更适合这种搜索用例。 –

回答

0

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

由于数组总是评估为真,此查询:

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'。您可以通过lambda函数访问文档,请参阅filter documentation上的示例。