2014-04-02 63 views
11

我的過濾器分組在一起分類。 我想檢索文檔,其中文檔可以匹配任何類別中的任何篩選器,但如果設置了兩個(或更多)類別,則文檔必須與所有類別中的任何篩選器匹配。如何在ElasticSearch中嵌套AND和OR過濾器?

如果用僞SQL將是:

SELECT * FROM Documents WHERE (CategoryA = 'A') AND (CategoryB = 'B' OR CategoryB = 'C') 

我已經試過像這樣的嵌套過濾器:

{ 
    "sort": [{ 
     "orderDate": "desc" 
    }], 
    "size": 25, 
    "query": { 
     "match_all": {} 
    }, 
    "filter": { 
     "and": [{ 
      "nested": { 
       "path":"hits._source", 
       "filter": { 
        "or": [{ 
         "term": { 
          "progress": "incomplete" 
         } 
        }, { 
         "term": { 
          "progress": "completed" 
         } 
        }] 
       } 
      } 
     }, { 
      "nested": { 
       "path":"hits._source", 
       "filter": { 
        "or": [{ 
         "term": { 
          "paid": "yes" 
         } 
        }, { 
         "term": { 
          "paid": "no" 
         } 
        }] 
       } 
      } 
     }] 
    } 
} 

但顯然我不太明白ES語法。這是正確的軌道還是我需要使用另一個過濾器?

+0

沒有答案過濾這個問題:''或''''term''可以通過[terms]更容易完成(http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-terms- filter.html)。而[bool](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html)的默認值是''和''。 「filter.bool.must:[{terms:progress:[」incomplete「,」complete「]}}。 {terms:paid:[「yes」,「no」]}]''可能會工作嗎? – cfrick

+0

嵌套查詢/過濾器用於數組/列表(取決於您熟悉的語言,例如'a = [{'b':1},{'c':2}])''。你能寫一個你的文件的例子嗎?這將有助於 – Diolor

+0

cfrick帶領我走上正確的道路。我在「和」過濾器中嵌入了一堆「條款」過濾器,它似乎滿足我的需求。 – MHTri

回答

3

雖然我還沒有完全理解你的結構,這可能是你需要的。

你必須樹思考。你必須創建一個布爾(=和)完成嵌入布爾。每個嵌入檢查該字段是否不存在,否則(在此使用而不是必須)該字段必須(此處的術語)是列表中的值之一。

不知道是否有更好的方法,不知道性能。

{ 
    "sort": [ 
     { 
      "orderDate": "desc" 
     } 
    ], 
    "size": 25, 
    "query": { 
     "query": {   # 
      "match_all": {} # These three lines are not necessary 
     },     # 
     "filtered": { 
      "filter": { 
       "bool": { 
        "must": [ 
         { 
          "bool": { 
           "should": [ 
            { 
             "not": { 
              "exists": { 
               "field": "progress" 
              } 
             } 
            }, 
            { 
             "terms": { 
              "progress": [ 
               "incomplete", 
               "complete" 
              ] 
             } 
            } 
           ] 
          } 
         }, 
         { 
          "bool": { 
           "should": [ 
            { 
             "not": { 
              "exists": { 
               "field": "paid" 
              } 
             } 
            }, 
            { 
             "terms": { 
              "paid": [ 
               "yes", 
               "no" 
              ] 
             } 
            } 
           ] 
          } 
         } 
        ] 
       } 
      } 
     } 
    } 
} 
+2

這是不正確的。 「必須」和「應該」不是''和'和'或'的別名。他們有不同的功能(雖然概念上有相似之處) –

8

這應該是它(從給出的僞SQL翻譯)

{ 
    "sort": [ 
     { 
     "orderDate": "desc" 
     } 
    ], 
    "size": 25, 
    "query": 
    { 
     "filtered": 
     { 
      "filter": 
      { 
       "and": 
       [ 
        { "term": { "CategoryA":"A" } }, 
        { 
         "or": 
         [ 
          { "term": { "CategoryB":"B" } }, 
          { "term": { "CategoryB":"C" } } 
         ] 
        } 
       ] 
      } 
     } 
    } 
} 

我知道你不提,但面只是爲了完整起見:

您也可以使用一個filter作爲基礎(像你一樣)而不是filtered query(就像我做的那樣)。將得到的JSON是,不同之處幾乎相同:

  • 一個過濾查詢將過濾兩者的主要結果以及面
  • 一個過濾器將只過濾NOT主要結果的刻面。

最後,嵌套過濾器(您嘗試使用),不涉及「嵌套過濾器」像你似乎相信,但涉及到對嵌套的文檔(親子)

相關問題