elasticsearch拼寫糾錯之Term Suggester

無風聽海發表於2022-01-16

一、什麼是拼寫糾錯

拼寫糾錯就是搜尋引擎可以智慧的感知使用者輸入關鍵字的錯誤,並使用糾正過的關鍵字進行搜尋展示給使用者;拼寫糾錯是一種改善使用者體驗的功能;

elasticsearch提供了以下不同型別的suggester來完成拼寫糾錯和自動完成功能;

term suggester主要針對單個的term分詞進行糾正的場景;

phrase suggester主要針對整個短語的拼寫糾正場景;

completion suggester主要提供一種快速高效的自動提示功能;

二、Term Suggester基於單個詞的拼寫糾錯

Term Suggester會將使用者輸入的text進行解析分解成單個的word,然後針對每個word進行糾錯;

elasticsearch的suggester請求的還是_search端點,要傳送一個Term suggester請求,我們需要

1.在body中新增suggest欄位;

2.指定我們的suggest的名字,我們可以使用不同的名字同時進行多個拼寫糾錯, 其最終的執行結果在response中也會使用這個名字進行區分;

3.通過text欄位指定要糾正的文字;

4.指定要使用的suggester型別,這裡使用term;

5.指定要在哪個欄位上進行拼寫糾錯;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "hots vlna",
      "term": {
        "field": "content"
      }
    }
  }
}

elasticsearch返回結果中的suggest部分包含對應的結果;

不同名字的suggester在返回結果中作為suggest物件的欄位,其作為陣列承載每個text分詞的建議結果;

每個原始的word作為一個物件,物件會記錄原始word的基本資訊及所有的建議詞;

每個建議詞物件會包含文字、打分、出現頻率;

{
  "suggest" : {
    "my_sug" : [
      {
        "text" : "hots",
        "offset" : 0,
        "length" : 4,
        "options" : [
          {
            "text" : "host",
            "score" : 0.75,
            "freq" : 109
          },
          {
            "text" : "http",
            "score" : 0.5,
            "freq" : 235
          },
          {
            "text" : "https",
            "score" : 0.5,
            "freq" : 9
          },
          {
            "text" : "hours",
            "score" : 0.5,
            "freq" : 6
          },
          {
            "text" : "hole",
            "score" : 0.5,
            "freq" : 5
          }
        ]
      },
      {
        "text" : "vlna",
        "offset" : 5,
        "length" : 4,
        "options" : [
          {
            "text" : "vlan",
            "score" : 0.75,
            "freq" : 200
          },
          {
            "text" : "vpna",
            "score" : 0.75,
            "freq" : 3
          },
          {
            "text" : "vlan1",
            "score" : 0.5,
            "freq" : 111
          },
          {
            "text" : "vlans",
            "score" : 0.5,
            "freq" : 11
          },
          {
            "text" : "vlan8",
            "score" : 0.5,
            "freq" : 10
          }
        ]
      }
    ]
  }
}

三、Term Suggester的通用配置選項

Term Suggester基於編輯距離來計算字串的相似性;如果一個建議詞通過更少字元的改變、新增、刪除來轉變成原始的字串,那麼這就是一個更好的建議詞;例如host通過變換t和s的位置變成hots,則二者的編輯距離是1;

text既可以在suggest裡邊單獨設定,也可以在全域性設定;

POST blogs/_search
{
  "suggest": {
    "text": "hots vlna",
    "content_sug": {
      "term": {
        "field": "content"
      }
    },
    "title_sug": {
      "term": {
        "field": "title"
      }
    }
  }
}

analyzer對text設定的文字進行analyse處理,預設使用field欄位的search analyzer;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "hots vlna",
      "term": {
        "analyzer":"standard",
        "field": "content"
      }
    }
  }
}

size設定每個word返回的建議詞的數量,預設是5個;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "hots vlna",
      "term": {
        "analyzer":"standard",
        "field": "content",
        "size":6
      }
    }
  }
}

sort設定每個word對應的建議詞的排序方式,由於每個建議詞只包含text、score、freq,這就涉及以哪個欄位先排序;

score,先使用score排序,後使用freq排序,最後使用建議詞排序;
frequency,先使用freq排序,後使用score排序,最後使用建議詞排序;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "hots",
      "term": {
        "field": "content",
        "sort":"frequency"
      }
    }
  }
}


{
  "suggest" : {
    "my_sug" : [
      {
        "text" : "hots",
        "offset" : 0,
        "length" : 4,
        "options" : [
          {
            "text" : "http",
            "score" : 0.5,
            "freq" : 235
          },
          {
            "text" : "host",
            "score" : 0.75,
            "freq" : 109
          },
          {
            "text" : "https",
            "score" : 0.5,
            "freq" : 9
          },
          {
            "text" : "hours",
            "score" : 0.5,
            "freq" : 6
          },
          {
            "text" : "hole",
            "score" : 0.5,
            "freq" : 5
          }
        ]
      }
    ]
  }
}

suggest_mode,主要控制針對什麼樣的詞會返回建議詞,以及返回那些建議詞;

missing,預設的選項,只有輸入的詞在對應欄位的分詞中不存在,才有可能返回建議詞;

popular,只返回在更多的文件中出現的建議詞;

always,任何的建議詞都可以返回;

由於vlan322在欄位content裡已經存在,使用missing模式沒有任何返回結果;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "vlan322",
      "term": {
        "field": "content",
        "suggest_mode":"missing"
      }
    }
  }
}

{
  "suggest" : {
    "my_sug" : [
      {
        "text" : "vlan322",
        "offset" : 0,
        "length" : 7,
        "options" : [ ]
      }
    ]
  }
}

使用popular模式則會返回對應的建議詞;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "vlan322",
      "term": {
        "field": "content",
        "suggest_mode":"popular"
      }
    }
  }
}

{
  "suggest" : {
    "my_sug" : [
      {
        "text" : "vlan322",
        "offset" : 0,
        "length" : 7,
        "options" : [
          {
            "text" : "vlan0022",
            "score" : 0.71428573,
            "freq" : 5
          },
          {
            "text" : "vlan30",
            "score" : 0.6666666,
            "freq" : 14
          },
          {
            "text" : "vlan20",
            "score" : 0.6666666,
            "freq" : 7
          },
          {
            "text" : "vlan.2",
            "score" : 0.6666666,
            "freq" : 6
          },
          {
            "text" : "vlan12",
            "score" : 0.6666666,
            "freq" : 6
          }
        ]
      }
    ]
  }
}

四、Term Suggester的專有配置選項

max_edits,主要控制可以包含的最大編輯距離的建議詞,可以取值1或者2,預設值為2;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "vlan322",
      "term": {
        "field": "content",
        "max_edits":1
      }
    }
  }
}

{
  "suggest" : {
    "my_sug" : [
      {
        "text" : "htpt",
        "offset" : 0,
        "length" : 4,
        "options" : [
          {
            "text" : "http",
            "score" : 0.75,
            "freq" : 235
          }
        ]
      }
    ]
  }
}

prefix_length,主要控制原始word的開頭多少個字元不參與拼錯糾正,預設值為1,提高這個值可以提高效能;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "vlan322",
      "term": {
        "field": "content",
        "prefix_length":2
      }
    }
  }
}

{
  "suggest" : {
    "my_sug" : [
      {
        "text" : "htpt",
        "offset" : 0,
        "length" : 4,
        "options" : [ ]
      }
    ]
  }
}

min_word_length,控制建議詞的最小字元長度,預設是4;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "vlan32",
      "term": {
        "field": "content",
        "min_word_length":7
      }
    }
  }
}

shard_size,主要控制每個分片返回的建議詞的數量,通過增大這個設定數量可以提高建議詞的準確性,但是可能會降低整體的效能;預設值跟size保持一致;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "vlan32",
      "term": {
        "field": "content",
        "shard_size":3,
        "size":10,
      }
    }
  }
}


{
  "suggest" : {
    "my_sug" : [
      {
        "text" : "vlan32",
        "offset" : 0,
        "length" : 6,
        "options" : [
          {
            "text" : "vlan30",
            "score" : 0.8333333,
            "freq" : 14
          },
          {
            "text" : "vlan.2",
            "score" : 0.8333333,
            "freq" : 6
          },
          {
            "text" : "vlan12",
            "score" : 0.8333333,
            "freq" : 6
          }
        ]
      }
    ]
  }
}

max_inspections,通過與shards_size相乘控制shard級別檢測可選建議詞的數量,預設值5;沒有測試出具體的效果;

min_doc_freq,主要控制返回建議詞至少在index中至少多個document中出現過,預設值為0,通過提高這個值可以提高準確率,可以設定具體的值也可以設定百分比;這是一個基於shard level配置選項;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "vlan32",
      "term": {
        "field": "content",
        "min_doc_freq":3
      }
    }
  }
}

{
  "suggest" : {
    "my_sug" : [
      {
        "text" : "vlan32",
        "offset" : 0,
        "length" : 6,
        "options" : [
          {
            "text" : "vlan30",
            "score" : 0.8333333,
            "freq" : 14
          },
          {
            "text" : "vlan.2",
            "score" : 0.8333333,
            "freq" : 6
          },
          {
            "text" : "vlan12",
            "score" : 0.8333333,
            "freq" : 6
          },
          {
            "text" : "vlan2",
            "score" : 0.8,
            "freq" : 8
          },
          {
            "text" : "vlan10",
            "score" : 0.6666666,
            "freq" : 55
          }
        ]
      }
    ]
  }
}

max_term_freq,主要控制建議詞在文件中出現的最多的次數,可以設定具體數值和百分比;預設值0.01f;降低這個值可以排除更多的建議詞從而提高效能;這個也是shard級別的配置;

POST blogs/_search
{
  "suggest": {
    "my_sug": {
      "text": "vlan32",
      "term": {
        "field": "content",
        "max_term_freq":1
      }
    }
  }
}

string_distance,設定計算編輯距離的具體演算法,可選值有internal、damerau_levenshtein、levenshtein、jaro_winkler、ngram;

相關文章