Elasticsearch:fuzzy 搜索 (模糊搜索)
在實際的搜索中,我們有時候會打錯字,從而導致搜索不到。在 Elasticsearch 中,我們可以使用 fuzziness 屬性來進行模糊查詢,從而達到搜索有錯別字的情形。
match 查詢具有 “fuziness” 屬性。它可以被設置為 “0”, “1”, “2”或 “auto”。“auto” 是推薦的選項,它會根據查詢詞的長度定義距離。在實際的使用中,當我們使用 auto 時,如果字符串的長度大于5,那么 funziness 的值自動設置為2,如果字符串的長度小于2,那么 fuziness 的值自動設置為 0。
Fuzzy query
返回包含與搜索詞相似的詞的文檔,以?Levenshtein 編輯距離?測量。
編輯距離是將一個術語轉換為另一個術語所需的一個字符更改的次數。 這些更改可以包括:
- 更改字符(box→fox)
- 刪除字符(black→lack)
- 插入字符(sic→sick)
- 轉置兩個相鄰字符(act→cat)
為了找到相似的詞,模糊查詢會在指定的編輯距離內創建搜索詞的所有可能變化或擴展的集合。 查詢然后返回每個擴展的完全匹配。
例子
我們首先輸入如下的一個文檔到 fuzzyindex 索引中:
PUT fuzzyindex/_doc/1 {"content": "I like blue sky" }如果這個時候,我們進行如下的搜索:
GET fuzzyindex/_search {"query": {"match": {"content": "ski"}} }那么是沒有任何被搜索到的結果,這是因為 “I like blue sky"? 里分詞后沒有 ski 這個詞。
{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 0,"relation" : "eq"},"max_score" : null,"hits" : [ ]} }這個時候,如果我們使用如下的搜索:
GET fuzzyindex/_search {"query": {"match": {"content": {"query": "ski","fuzziness": "1"}}} }那么顯示的結果是:
{"took" : 18,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.19178805,"hits" : [{"_index" : "fuzzyindex","_type" : "_doc","_id" : "1","_score" : 0.19178805,"_source" : {"content" : "I like blue sky"}}]} }顯然是找到我們需要的結果了。這是因為 sky?和 ski?時間上是只差別一個字母。
同樣,如果我們選用“auto”選項看看:
GET fuzzyindex/_search {"query": {"match": {"content": {"query": "ski","fuzziness": "auto"}}} }它顯示的結果和上面的是一樣的。也可以進行匹配。
如果我們進行如下的匹配:
GET fuzzyindex/_search {"query": {"match": {"content": {"query": "bxxe","fuzziness": "auto"}}} }那么它不能匹配任何的結果,但是,如果我們進行如下的搜索:
GET fuzzyindex/_search {"query": {"match": {"content": {"query": "bxxe","fuzziness": "2"}}} }我們也可以使用如下的格式:
GET /_search {"query": {"fuzzy": {"content": {"value": "bxxe","fuzziness": "2"}}} }那么它可以顯示搜索的結果,這是因為我們能夠容許兩個編輯的錯誤。
我們接著再做一個試驗:
GET fuzzyindex/_search {"query": {"match": {"content": {"query": "bluo ski","fuzziness": 1}}} }上面顯示的結果是:
{"took" : 17,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.40754962,"hits" : [{"_index" : "fuzzyindex","_type" : "_doc","_id" : "1","_score" : 0.40754962,"_source" : {"content" : "I like blue sky"}}]} }在上面的搜索中 “bluo ski”,這個詞語有兩個錯誤。我們想,是不是超過了我們定義的 "funziness": 1。其實不是的。 fuziness 為1,表示是針對每個詞語而言的,而不是總的錯誤的數值。
在 Elasticsearch 中,有一個單獨的 fuzzy 搜索,但是這個只針對一個 term 比較有用。其功能和上面的是差不多的:
GET fuzzyindex/_search {"query": {"fuzzy": {"content": {"value": "ski","fuzziness": 1}}} }上面的搜索返回的結果是:
{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.19178805,"hits" : [{"_index" : "fuzzyindex","_type" : "_doc","_id" : "1","_score" : 0.19178805,"_source" : {"content" : "I like blue sky"}}]} }總結
模糊性是拼寫錯誤的簡單解決方案,但具有很高的 CPU 開銷和非常低的精度。
?參考:
【1】Fuzzy query | Elasticsearch Guide [7.4] | Elastic
總結
以上是生活随笔為你收集整理的Elasticsearch:fuzzy 搜索 (模糊搜索)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 产品经理入门到大神的资料全推荐
- 下一篇: 项目管理常见的输入输出