本篇文章主要說明match執行過程中的低級查詢(bool term)以及涉及到評分規則(包括同義詞)。elasticsearch一些較複雜業
務查詢中 match 多詞和同義詞搜索可能會遇到的問題。
match或者query_string這樣的查詢是高級查詢(High-level Queries),它們能夠理解一個字段的映射,一旦查詢得到了一個詞條列表,
它就會使用列表中的每個詞條來執行合適的低級查詢,然後將得到的結果進行合併,最終產生每份文檔的相關度分值。term是代表完全
匹配,即不進行分詞器分析,文檔中必須包含整個搜索的詞彙,只會在倒排索引中尋找該詞條的精確匹配。
業務場景:有個title爲“衣服很漂亮”,其中“衣服”對應同義詞“服飾”、“服裝”兩個。
A:搜索關鍵字:“穿服飾”。
B:搜索關鍵字爲:“服飾”。
match查詢應該是你的首選。它是一個高級全文查詢,意味着它知道如何處理全文字段(Full-text, analyzed)和精確值字段(Exact-
value,not_analyzed)。直接用match查詢很容易滿足該業務實現A。其中minimum_should_match 設置爲67%,向下取整數,控制匹配精
度。DSL實現語句如下:
{
"explain": true,
"fields": [
"title"
],
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"match": {
"title.ik": {
"query": “穿服裝",
"minimum_should_match": "67%"
}
}
}
]
}
},
"filter": {
"bool": {
"must": {
"term": {
"cityId": 310100
}
}
}
}
}
}
}
不難發現A很好實現,但是B,只單是搜索“衣服”,那麼就出現問題了,會出現搜索不到結果的情況,爲什麼會出現這種情況????
因爲同義詞有3個!!!而minimum_should_match=“67%",3*67%=2.01,必須至少匹配兩個。所以B是搜索不出來結果的。分解成低級
bool查詢的時候,檢索關係:“穿” OR (“衣服” OR “服飾” OR “服裝” ) DSL如下:
{
"bool": {
"should": [
{
"term": {
"title.ik": "衣服"
}
},
{
"term": {
"title.ik": "服飾"
}
},
{
"term": {
"title.ik": "服裝"
}
}
]
}
}
match查詢的多詞查詢只是簡單地將生成的term查詢包含在了一個bool查詢中。通過默認的or操作符,每個term查詢都以一個語句
被添加,所以至少一個should語句需要被匹配。bool 查詢默認會對所有 should 語句使用協調功能,當我們使用 bool 查詢將多個高級查
詢如 match 查詢包裹的時候,讓協調功能打開是有意義的,匹配的語句越多,查詢請求與返回文檔間的重疊度就越高。
但在某些高級應用中,我們將協調功能關閉可能更好。假如我們正在查找同義詞 “衣服”,“服裝”,“服飾”。我們並不關心會出現
多少個同義詞,因爲它們都表示一個意思,實際上,只有其中一個同義詞會出現,當我們使用同義詞的時候(參照:同義詞
(Synonyms)),Lucene內部是這樣的:重寫的的查詢會爲同義詞關閉協調功能(coord=1),大多數關閉操作的應用場景是自動處理
的,無須爲此擔心。對於elasticsearch match查詢來說,遇到同義詞的時候,也會自動爲同義詞關閉協調功能。通過
disable_coord=ture實現對A的DSL macth查詢的解析。
對應的的DSL應該如下:
{
"explain": true,
"fields": [
"title"
],
"query": {
"filtered": {
"query": {
"bool": {
"minimum_should_match": "67%",
"should": [
{
"term": {
"title.ik": "穿"
}
},
{
"bool": {
"disable_coord": true,
"should": [
{
"term": {
"title.ik": "衣服"
}
},
{
"term": {
"title.ik": "服飾"
}
},
{
"term": {
"title.ik": "服裝"
}
}
]
}
}
]
}
},
"filter": {
"bool": {
"must": {
"term": {
"cityId": 310100
}
}
}
}
}
}
}