1. 程式人生 > >基於elasticsearch的搜尋自動糾錯

基於elasticsearch的搜尋自動糾錯

作者: 馬努
elasticsearch是一個全文搜尋引擎,能在大量資料中提供快速、準確的檢索,同時它也提供了一些改善搜尋體驗的功能。如下兩張圖所示,我們在搜尋的時候經常會因為手誤或者不確定,出現輸入的搜尋關鍵字錯誤的情況,當前流行的谷歌和百度都會給出提示,“以下為您顯示”或者“Showing results for”,本文解釋如何用suggest api更正搜尋中的拼寫,提供搜尋建議功能。

這裡寫圖片描述

這裡寫圖片描述

準備測試資料

我們索引一些測試資料,來說明糾錯建議的實現,以下是我們準備的測試資料。

curl -XPOST localhost:9200/suggester_test/my_type/_bulk -d '
{"
index": {"_id": 1}} {"testfield": "Elasticsearch is based on lucene"} {"index": {"_id": 2}} {"testfield": "Elasticsearch is based on lucne"} {"index": {"_id": 3}} {"testfield": "Elasticsearch and solr are based on lucene"} {"index": {"_id": 4}} {"testfield": "Elasticsearch is open source"} {"index": {"
_id": 5}} {"testfield": "Elasticserch is open source"} '

term suggester

term suggester基於編輯距離的匹配查詢,建議的文字在查詢之前進行分詞,根據分詞的結果得到每個詞的建議結果。如下查詢:

curl -XPOST localhost:9200/suggester_test/_search?pretty -d '{
 "size": 0,
 "suggest": {
   "text": "elasticsrch lucene",
   "my-suggestion": {
     "term": {
       "
field": "testfield", "suggest_mode": "always" } } } }'

我們查詢“Elasticsrch lucene”,其term suggest結果如下

{
  "took" : 26,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 5,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "suggest" : {
    "my-suggestion" : [ {
      "text" : "elasticsrch",
      "offset" : 0,
      "length" : 11,
      "options" : [ {
        "text" : "elasticserch",
        "score" : 0.9090909,
        "freq" : 1
      }, {
        "text" : "elasticsearch",
        "score" : 0.8181818,
        "freq" : 3
      } ]
    }, {
      "text" : "lucene",
      "offset" : 12,
      "length" : 6,
      "options" : [ {
        "text" : "lucne",
        "score" : 0.8,
        "freq" : 1
      } ]
    } ]
  }
}

“elasticsrch lucene”經過分詞之後產生了elasticsrch 和lucene兩個詞根,得到的建議結果分別是elasticsrch, elasticsearch和lucne(此處為了說明情況,特意索引了拼寫相似的單詞)。elasticsrch的糾正結果是elasticserch和elasticsearch其中elasticserch更相似,假如實際中搜索建議給出了兩個相似拼寫的建議值,我們不能確定那個更合適;對於lecene得到lucne,因為我們庫中的髒資料給出了錯誤的建議。如果庫中資料存在髒資料,對於term suggest會起到反作用,對正確的資料給出錯誤的建議。

phrase suggester

phrase suggester在term suggester之上添加了額外的邏輯以選擇整體更正的phrase,而不是基於單個分詞加權的ngram語言模型。在實際中phrase suggester能夠根據單詞的詞頻等資訊作出更好的選擇。

curl -XPOST localhost:9200/suggester_test/_search?pretty -d '{
 "size": 0,
 "suggest": {
   "text": "elasticsrch lucene",
   "my-suggestion": {
     "phrase": {
       "field": "testfield",
       "confidence": 0,
       "collate": {
         "query": {
           "inline": {
             "match": {
               "{{field_name}}" : "{{suggestion}}"
             }
           }
         },
         "params": {"field_name" : "testfield"},
         "prune": true
       }
     }
   }
 }
}'

查詢結果如下:

{
  "took" : 23,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 5,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "suggest" : {
    "my-suggestion" : [ {
      "text" : "elasticsrch lucene",
      "offset" : 0,
      "length" : 18,
      "options" : [ {
        "text" : "elasticsearch lucene",
        "score" : 0.2214925,
        "collate_match" : true
      }, {
        "text" : "elasticserch lucene",
        "score" : 0.20829101,
        "collate_match" : true
      }, {
        "text" : "elasticsrch lucene",
        "score" : 0.17490317,
        "collate_match" : false
      }, {
        "text" : "elasticsrch lucne",
        "score" : 0.10791662,
        "collate_match" : true
      } ]
    } ]
  }
}

查詢結果給出單個詞根糾錯結果的所有組合,並且給出了collate_match屬性,collate_match是collate條件產生的,collate會將當前的建議自動變為{{suggestion}}變數進行指定查詢,如果prune設定為true時,這些建議將有一個額外的選項collate_match,如果找到了與短語匹配的文件,該選項將為true,否則為false。我們可以根據_score和prune對建議結果進行篩選,給出搜尋建議。

總結

本文主要介紹李suggest api的使用,並結合實際場景分析李如何利用suggest api實現搜尋中的自動糾錯建議。