elasticsearch控制match執行過程的低級查詢處理規則

本篇文章主要說明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
            }
          }
        }
      }
    }
  }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章