如何使用SymSpell將模糊搜尋速度提高五倍以上 - lnx

banq發表於2021-11-25

這是對相當令人難以置信的 SymSpell 演算法以及我們如何在 lnx 中實現它的一個相當普遍的看法。

我在開發 lnx 時遇到的最酷的功能之一是一種稱為 SymSpell 的演算法:https://github.com/lnx-search/lnx

每當您希望搜尋引擎解決使用者的輸入錯誤時,您都必須計算應用到某個單詞所需的更改以獲得目標單詞。

例如,如果我要糾正Beer到Bree我們必須應用兩詞取代過程,兩個步驟分解為:

  • - Beer -> Brer+1  替換e為r.
  • - Brer -> Bree +1  替換r為e.

現在,這是一個相對簡單的過程,當您有數百萬個單詞要搜尋並與整個句子進行比較時,問題就來了。突然間,您發現自己進行了數百萬次迭代來實現這種錯字容忍度。當檢視更大的索引時,尤其是當您有很多使用者要搜尋請求時,這就是事情開始變得非常緩慢、非常快的地方。

現在,大多數情況下,搜尋引擎都採用根據字長計算最大編輯距離的策略,這有助於通過不過度寬容匹配相似詞來提高相關性,而且還有助於提高效能,因為大多數詞的編輯距離為 0或 1 比允許每個單詞的最大編輯距離為 2 節省大量計算。這同樣是一種權衡,然而,即使一個非常常見的錯誤是 helo 或類似的錯誤,像 hello 這樣的詞只會被賦予 0 的編輯距離,與純全文搜尋相比,它仍然相當慢。

當我們增長到更大的索引(在本例中為 20GB 的文字)時,當在我的本地機器上以相當高的 5GHz 時鐘速度和 NVMe 隨時僅執行 1 個併發客戶端時,我們的驅動器延遲會猛增。

因此,在這種情況下,我們只剩下三個選項:

  • 增加單機或分片搜尋請求的計算能力。
  • 刪除可搜尋文字的數量。
  • 摒棄錯別字容忍度。

。。。。

 

什麼是 SymSpell

SymSpell 分解為對稱刪除拼寫校正演算法:

從每個字典術語生成具有編輯距離(僅刪除)的術語,並將它們與原始術語一起新增到字典中。這必須在預計算步驟中僅執行一次。生成與輸入術語具有編輯距離(僅刪除)的術語並在字典中搜尋它們。對於長度為 n 的單詞、字母大小為 a、編輯距離為 1 的單詞,將只有 n 個刪除,在搜尋時總共有 n 個術語。 - 有關更多資訊,請檢視Wolf Garbe 的部落格

總的來說,這使得更正的成本大大降低,代價是一些預先計算和記憶體使用(預先計算的字典儲存在記憶體中)但是,這使得它很難在搜尋引擎中使用,並且需要這樣做許多嘗試和設計迭代使其在 lnx 中工作。

更多點選標題

 

相關文章