2012-10-01 42 views
17

我正在尋找一種方法來做確切的彈性搜索中的數組匹配。 比方說,這是我的證件:使用elasticsearch精確搜索數組對象類型

{"id": 1, "categories" : ["c", "d"]} 
{"id": 2, "categories" : ["b", "c", "d"]} 
{"id": 3, "categories" : ["c", "d", "e"]} 
{"id": 4, "categories" : ["d"]} 
{"id": 5, "categories" : ["c", "d"]} 

有沒有一種方法來搜索所有文件的有正是類別「c」和「d」(文件1和5),沒有多還是少?

還有一個好處:在搜索類別「這一個」應該還是可能的(例如,你可以搜索「C」,並獲得1,2,3和5)

任何聰明的方式,解決這個問題?

回答

19

如果你有一個不連續的,已知的一組類,您可以使用布爾查詢:

"bool" : { 
    "must" : { 
     "terms" : { "categories" : ["c", "d"], 
      minimum_should_match : 2 
     } 
    }, 
    "must_not" : { 
     "terms" : { "categories" : ["a", "b", "e"], 
      minimum_should_match : 1 
     } 
    } 
} 

否則,也許最簡單的方式來做到這一點,我想,是存儲其他領域作爲類別關鍵字。

{"id": 1, "categories" : ["c", "d"], "categorieskey" : "cd"} 

就是這樣的。然後,你可以很容易地與精確的結果,你想詞語查詢,查詢功能:

term { "categorieskey" : "cd" } 

而且你仍然可以搜索非排他性,如;

term { "categories" : "c" } 

查詢兩類必須同時存在是很容易的,但隨後防止任何其他潛在的類別從存在是有點困難。可能你可以做到。您可能想要編寫一個查詢來查找包含兩者的記錄,然後對其應用過濾器,以消除除指定範圍以外的任何記錄。就我所知,Lucene實際上並不是一種真正的搜索。

老實說,我有一個麻煩想出一個很好的過濾器在這裏使用。您可能需要腳本過濾器,或者您可以在檢索結果後過濾結果。

+1

可笑,這正是我告訴他:) – phoet

+0

@phoet你太聰明瞭;) – paukul

+0

@femtoRgon謝謝!不幸的是這是個壞消息:) – paukul

1

我發現我們的使用情況似乎有效的解決方案。它依賴於兩個過濾器,以及我們想要匹配多少類別的知識。我們利用術語過濾器和腳本過濾器來檢查數組的大小。在這個例子中,marketBasketList類似於您的類別條目。

{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "match": { 
      "siteId": 4 
      } 
     }, 
     { 
      "match": { 
      "marketBasketList": { 
       "query": [ 
       10, 
       11 
       ], 
       "operator": "and" 
      } 
      } 
     } 
     ] 
    }, 
    "boost": 1, 
    "filter": { 
     "and": { 
     "filters": [ 
      { 
      "script": { 
       "script": "doc['marketBasketList'].values.length == 2" 
      } 
      }, 
      { 
      "terms": { 
       "marketBasketList": [ 
       10, 
       11 
       ], 
       "execution": "and" 
      } 
      } 
     ] 
     } 
    } 
    } 
}