2017-09-21 27 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上的示例。