日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Elasticsearch: Ngrams, edge ngrams, and shingles

發(fā)布時(shí)間:2023/12/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Elasticsearch: Ngrams, edge ngrams, and shingles 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Ngrams 和 edge ngrams 是在 Elasticsearch 中 token 文本的兩種更獨(dú)特的方式。 Ngrams 是一種將一個 token 分成一個單詞的每個部分的多個子字符的方法。 ngram 和 edge ngram 過濾器都允許你指定 min_gram 以及 max_gram 設(shè)置。 這些設(shè)置控制單詞被分割成的 token 的大小。 這可能令人困惑,讓我們看一個例子。 假設(shè)你想用 ngram 分析儀分析 “spaghetti” 這個詞,讓我們從最簡單的情況開始,1-gams(也稱為 unigrams)。

在實(shí)際的搜索例子中,比如谷歌搜索:

每當(dāng)我們打入前面的幾個字母時(shí),就會出現(xiàn)相應(yīng)的很多的候選名單。這個就是 autocomplete 功能。在 Elasticsearch 中,我們可以通過 Edge ngram 來實(shí)現(xiàn)這個目的。

1-grams

“spaghetti” 的 1-grams 是 s,p,a,g,h,e,t,t,i。 根據(jù) ngram 的大小將字符串拆分為較小的 token。 在這種情況下,每個 token 都是一個字符,因?yàn)槲覀冋務(wù)摰氖?unigrams。

Bigrams

如果你要將字符串拆分為雙字母組(這意味著大小為2),你將獲得以下較小的 token:sp,pa,ag,gh,he,et,tt,ti。

Trigrams

再說一次,如果你要使用三個大小,你將得到 token 為 spa,pag,agh,ghe,het,ett,tti。

設(shè)置 min_gram 和 max_gram

使用此分析器時(shí),需要設(shè)置兩種不同的大小:一種指定要生成的最小 ngrams(min_gram 設(shè)置),另一種指定要生成的最大 ngrams。 使用前面的示例,如果你指定 min_gram 為 2 且 max_gram 為 3,則你將獲得前兩個示例中的組合分詞:

sp, spa, pa, pag, ag, agh, gh, ghe, he, het, et, ett, tt, tti, ti

如果你要將 min_gram 設(shè)置為1并將 max_gram 設(shè)置為3,那么你將得到更多的 token,從 s,sp,spa,p,pa,pag,a,....開始。

以這種方式分析文本具有一個有趣的優(yōu)點(diǎn)。 當(dāng)你查詢文本時(shí),你的查詢將以相同的方式被分割成文本,所以說你正在尋找拼寫錯誤的單詞“ spaghety”。搜索這個的一種方法是做一個?fuzzy query,它允許你 指定單詞的編輯距離以檢查匹配。 但是你可以通過使用 ngrams 來獲得類似的行為。 讓我們將原始單詞(“spaghetti”)生成的 bigrams 與拼寫錯誤的單詞(“spaghety”)進(jìn)行比較:

  • “spaghetti” 的 bigrams:sp,pa,ag,gh,he,et,tt,ti
  • “spaghety” 的 bigrams:sp,pa,ag,gh,he,et,ty

你可以看到六個 token 重疊,因此當(dāng)查詢包含 “spaghety” 時(shí),其中帶有 “spaghetti” 的單詞仍然匹配。請記住,這意味著你可能不打算使用的原始 “spaghetti” 單詞更多的單詞 ,所以請務(wù)必測試你的查詢相關(guān)性!

ngrams 做的另一個有用的事情是允許你在事先不了解語言時(shí)或者當(dāng)你使用與其他歐洲語言不同的方式組合單詞的語言時(shí)分析文本。 這還有一個優(yōu)點(diǎn),即能夠使用單個分析器處理多種語言,而不必指定。

Edge ngrams

常規(guī) ngram 拆分的變體稱為 edge ngrams,僅從前沿構(gòu)建 ngram。 在 “spaghetti” 示例中,如果將 min_gram 設(shè)置為2并將 max_gram 設(shè)置為6,則會獲得以下 token:

sp, spa, spag, spagh, spaghe

你可以看到每個 token 都是從邊緣構(gòu)建的。 這有助于搜索共享相同前綴的單詞而無需實(shí)際執(zhí)行前綴查詢。 如果你需要從一個單詞的后面構(gòu)建 ngrams,你可以使用 side 屬性從后面而不是默認(rèn)前面獲取邊緣。

它和 ngram 的區(qū)別在于:

Ngram 設(shè)置

當(dāng)你不知道語言是什么時(shí),Ngrams 是分析文本的好方法,因?yàn)樗鼈兛梢苑治鰡卧~之間沒有空格的語言。 使用 min 和 max grams 配置 edge ngram analyzer 的示例如下所示:

PUT my_index {"settings": {"analysis": {"analyzer": {"my_analyzer": {"tokenizer": "my_tokenizer"}},"tokenizer": {"my_tokenizer": {"type": "edge_ngram","min_gram": 2,"max_gram": 10,"token_chars": ["letter","digit"]}}}} }

我們可以用剛才創(chuàng)建的 my_tokenizer 來分析我們的字符串:

POST my_index/_analyze {"analyzer": "my_analyzer","text": "2 Quick Foxes." }

顯示的結(jié)果是:

{"tokens" : [{"token" : "Qu","start_offset" : 2,"end_offset" : 4,"type" : "word","position" : 0},{"token" : "Qui","start_offset" : 2,"end_offset" : 5,"type" : "word","position" : 1},{"token" : "Quic","start_offset" : 2,"end_offset" : 6,"type" : "word","position" : 2},{"token" : "Quick","start_offset" : 2,"end_offset" : 7,"type" : "word","position" : 3},{"token" : "Fo","start_offset" : 8,"end_offset" : 10,"type" : "word","position" : 4},{"token" : "Fox","start_offset" : 8,"end_offset" : 11,"type" : "word","position" : 5},{"token" : "Foxe","start_offset" : 8,"end_offset" : 12,"type" : "word","position" : 6},{"token" : "Foxes","start_offset" : 8,"end_offset" : 13,"type" : "word","position" : 7}] }

因?yàn)槲覀兌x的 min_gram 是2,所以生成的 token 的長度是從2開始的。

通常我們建議在索引時(shí)和搜索時(shí)使用相同的分析器。 在 edge_ngram tokenizer 的情況下,建議是不同的。 僅在索引時(shí)使用 edge_ngram?token 生成器才有意義,以確保部分單詞可用于索引中的匹配。 在搜索時(shí),只需搜索用戶輸入的術(shù)語,例如:Quick Fo。

下面是如何為搜索類型設(shè)置字段的示例:

PUT my_index {"settings": {"analysis": {"analyzer": {"autocomplete": {"tokenizer": "autocomplete","filter": ["lowercase"]},"autocomplete_search": {"tokenizer": "lowercase"}},"tokenizer": {"autocomplete": {"type": "edge_ngram","min_gram": 2,"max_gram": 10,"token_chars": ["letter"]}}}},"mappings": {"properties": {"title": {"type": "text","analyzer": "autocomplete","search_analyzer": "autocomplete_search"}}} }

在我們的例子中,我們索引時(shí)和搜索時(shí)時(shí)用了兩個不同的 analyzer:autocomplete 及 autocomplete_search。

PUT my_index/_doc/1 {"title": "Quick Foxes" }POST my_index/_refresh

上面我們加入一個文檔。下面我們來進(jìn)行搜索:

GET my_index/_search {"query": {"match": {"title": {"query": "Quick Fo", "operator": "and"}}} }

顯示結(jié)果:

{"took" : 3,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.5753642,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 0.5753642,"_source" : {"title" : "Quick Foxes"}}]} }

在這里 autocomplete analyzer 可以把字符串 “Quick Foxes” 分解為[qu, qui, quic, quick, fo, fox, foxe, foxes]。而自 autocomplete_search analyzer 搜索條目[quick,fo],兩者都出現(xiàn)在索引中。

當(dāng)然我們也可以做如下的搜索:

GET my_index/_search {"query": {"match": {"title": {"query": "Fo"}}} }

顯示的和上面一樣的結(jié)果。

Shingles

與 ngrams 和 edge ngrams一樣,有一個稱為 shingle 的過濾器(不,不是疾病的那個shingle!)。 Shingle token 過濾器基本上是 token 級別的 ngrams 而不是字符級別。


想想我們最喜歡的單詞 “spaghetti”。使用最小和最大設(shè)置為 1 和 3 的 ngrams,Elasticsearch 將生成分詞?s,sp,spa,p,pa,pag,a,ag等。 一個 shingle 過濾器在 token 級別執(zhí)行此操作,因此如果你有文本 “foo bar baz” 并再次使用 in_shingle_size 為?2 且 max_shingle_size 為 3,則你將生成以下 token:

foo, foo bar, foo bar baz, bar, bar baz, baz

為什么仍然包含單 token 輸出? 這是因?yàn)槟J(rèn)情況下,shingle 過濾器包含原始 token,因此原始 token 生成令牌 foo,bar 和 baz,然后將其傳遞給 shingle token 過濾器,生成分詞 foo bar,foo bar baz 和 bar baz。 所有這些 token 組合在一起形成最終 token 流。 你可以通過將 output_unigrams 選項(xiàng)設(shè)置為 false 來禁用此行為,也即不需要最原始的 token:foo, bar 及 baz

下一個清單顯示了 shingle token 過濾器的示例; 請注意,min_shingle_size 選項(xiàng)必須大于或等于2。

PUT my_index {"settings": {"analysis": {"analyzer": {"shingle": {"type": "custom","tokenizer": "standard","filter": ["shingle-filter"]}},"filter": {"shingle-filter": {"type": "shingle","min_shingle_size": 2,"max_shingle_size": 3,"output_unigrams": false}}}} }

在這里,我們定義了一個叫做 shingle-filter 的過濾器。最小的 shangle 大小是2,最大的 shingle 大小是3。同時(shí)我們設(shè)置 output_unigrams 為 false,這樣最初的那些 token 將不被包含在最終的結(jié)果之中。

下面我們來做一個例子,看看顯示的結(jié)果:

GET /my_index/_analyze {"text": "foo bar baz","analyzer": "shingle" }

顯示的結(jié)果為:
?

{"tokens" : [{"token" : "foo bar","start_offset" : 0,"end_offset" : 7,"type" : "shingle","position" : 0},{"token" : "foo bar baz","start_offset" : 0,"end_offset" : 11,"type" : "shingle","position" : 0,"positionLength" : 2},{"token" : "bar baz","start_offset" : 4,"end_offset" : 11,"type" : "shingle","position" : 1}] }

參考:

【1】?Edge NGram Tokenizer | Elasticsearch Guide [7.3] | Elastic

總結(jié)

以上是生活随笔為你收集整理的Elasticsearch: Ngrams, edge ngrams, and shingles的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。