本文已收錄至Github,推薦閱讀 ?? Java隨想錄
微信公眾號(hào):Java隨想錄
在 Elasticsearch 中,模糊搜索是一種近似匹配的搜索方式。它允許找到與搜索詞項(xiàng)相似但不完全相等的文檔。
前綴匹配:prefix
前綴匹配通過(guò)指定一個(gè)前綴值,搜索并匹配索引中指定字段的文檔,找出那些以該前綴開(kāi)頭的結(jié)果。
在 Elasticsearch 中,可以使用 prefix
查詢來(lái)執(zhí)行前綴搜索。其基本語(yǔ)法如下:
{
"query": {
"prefix": {
"field_name": {
"value": "prefix_value"
}
}
}
}
其中,field_name
是要進(jìn)行前綴搜索的字段名,prefix_value
是要匹配的前綴值。
注意:前綴搜索匹配的是term,而不是field,換句話說(shuō)前綴搜索匹配的是分析之后的詞項(xiàng),并且不計(jì)算相關(guān)度評(píng)分。
優(yōu)點(diǎn):
- 快速:前綴搜索使用倒排索引加速匹配過(guò)程,具有較高的查詢性能。
- 靈活:可以基于不同的字段進(jìn)行前綴搜索,適用于各種數(shù)據(jù)模型。
缺點(diǎn):
- 前綴無(wú)法通配:前綴搜索只能匹配以指定前綴開(kāi)始的文檔,無(wú)法進(jìn)行通配符匹配。
- 高內(nèi)存消耗:如果前綴值過(guò)長(zhǎng)或前綴匹配的文檔數(shù)量過(guò)多,將占用較大的內(nèi)存資源,并且前綴搜索是沒(méi)有緩存的。
index_prefixes
index_prefixes
參數(shù)允許對(duì)詞條前綴進(jìn)行索引,以加速前綴搜索。它接受以下可選設(shè)置:
- min_chars:索引的最小前綴長(zhǎng)度(包含),必須大于0,默認(rèn)值為2。
- max_chars:索引的最大前綴長(zhǎng)度(包含),必須小于20,默認(rèn)值為5。
index_prefixe可以理解為在索引上又建了層索引,會(huì)為詞項(xiàng)再創(chuàng)建倒排索引,會(huì)加快前綴搜索的時(shí)間,但是會(huì)浪費(fèi)大量空間,本質(zhì)還是空間換時(shí)間。
通配符匹配:wildcard
通配符匹配允許使用通配符來(lái)匹配文檔中的字段值,是一種基于模式匹配的搜索方法,它使用通配符字符來(lái)匹配文檔中的字段值。
通配符字符包括 *
和 ?
,其中 *
表示匹配任意數(shù)量(包括零個(gè))的字符,而 ?
則表示匹配一個(gè)字符。
在通配符搜索中,可以在搜索詞中使用通配符字符,將其替換為要匹配的任意字符或字符序列。通配符搜索可以應(yīng)用于具有文本類型的字段。
注意:通配符搜索和前綴搜索一樣,匹配的都是分析之后的詞項(xiàng)。
請(qǐng)求示例: 以下是一個(gè)使用通配符搜索的示例請(qǐng)求:
GET /my_index/_search
{
"query": {
"wildcard": {
"title.keyword": {
"value": "elast*"
}
}
}
}
在上述示例中,我們對(duì)名為 my_index
的索引執(zhí)行了一個(gè)通配符搜索。我們指定了要搜索的字段為 title.keyword
,并使用 elast*
作為通配符搜索詞。這將匹配 title.keyword
字段中以 elast
開(kāi)頭的任意字符序列。
正則表達(dá)式匹配:regexp
正則表達(dá)式匹配(regexp)是一種基于正則表達(dá)式模式進(jìn)行匹配的搜索方法,它允許使用正則表達(dá)式來(lái)匹配文檔中的字段值。
用途: 正則表達(dá)式匹配在以下情況下非常有用:
- 高級(jí)模式匹配:當(dāng)需要更復(fù)雜的模式匹配時(shí),正則表達(dá)式匹配提供了更多的靈活性和功能。
- 模糊搜索:通過(guò)使用通配符和限定符,可以進(jìn)行更精確的模糊匹配。
優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):
- 強(qiáng)大的模式匹配:正則表達(dá)式匹配提供了強(qiáng)大且靈活的模式匹配功能,可以滿足各種復(fù)雜的搜索需求。
- 可定制性:通過(guò)使用正則表達(dá)式,您可以根據(jù)具體需求編寫自定義的匹配規(guī)則。
- 缺點(diǎn):
- 性能:正則表達(dá)式匹配的性能較低,尤其是在大型索引上進(jìn)行正則表達(dá)式匹配可能會(huì)導(dǎo)致搜索延遲和資源消耗增加。
- 學(xué)習(xí)成本高:使用正則表達(dá)式需要一定的學(xué)習(xí)和理解,對(duì)于不熟悉正則表達(dá)式的人來(lái)說(shuō)可能會(huì)有一定的難度。
語(yǔ)法:
GET <index>/_search
{
"query": {
"regexp": {
"<field>": {
"value": "<regex>",
"flags": "ALL",
}
}
}
}
請(qǐng)求示例: 以下是一個(gè)使用正則表達(dá)式匹配的示例請(qǐng)求:
GET /my_index/_search
{
"query": {
"regexp": {
"title.keyword": {
"value": "elast.*",
"flags": "ALL"
}
}
}
}
在上述示例中,我們對(duì)名為 my_index
的索引執(zhí)行了一個(gè)正則表達(dá)式匹配。我們指定要搜索的字段為 title.keyword
,并使用 elast.*
作為正則表達(dá)式匹配模式。這將匹配 title.keyword
字段中以 elast
開(kāi)頭的字符序列,并且后面可以是任意字符。
注意:regexp查詢的性能可以根據(jù)提供的正則表達(dá)式而有所不同。為了提高性能,應(yīng)避免使用通配符模式,如 .
或 .?+
未經(jīng)前綴或后綴。
flags
正則表達(dá)式匹配的 flags
參數(shù)用于指定正則表達(dá)式的匹配選項(xiàng)。它可以修改正則表達(dá)式的行為以進(jìn)行更靈活和精確的匹配。
語(yǔ)法: 在正則表達(dá)式匹配的查詢中,flags
參數(shù)是一個(gè)字符串,它可以包含多個(gè)選項(xiàng),并用逗號(hào)分隔。每個(gè)選項(xiàng)都由一個(gè)字母表示。
以下是常用的 flags
參數(shù)選項(xiàng)及其說(shuō)明:
-
ALL
:?jiǎn)⒂盟羞x項(xiàng),相當(dāng)于同時(shí)啟用了ANYSTRING
,COMPLEMENT
,EMPTY
,INTERSECTION
,INTERVAL
,NONE
,NOTEMPTY
, 和NOTNONE
。 -
ANYSTRING
:允許使用.
來(lái)匹配任意字符,默認(rèn)情況下.
不匹配換行符。 -
COMPLEMENT
:求反操作,匹配除指定模式外的所有內(nèi)容。 -
EMPTY
:匹配空字符串。 -
INTERSECTION
:允許使用&&
運(yùn)算符來(lái)定義交集。 -
INTERVAL
:允許使用{}
來(lái)定義重復(fù)數(shù)量的區(qū)間。 -
NONE
:禁用所有選項(xiàng),相當(dāng)于不設(shè)置flags
參數(shù)。 -
NOTEMPTY
:匹配非空字符串。 -
NOTNONE
:匹配任何內(nèi)容,包括空字符串。
flags參數(shù)用到的場(chǎng)景比較少,做下了解即可。
模糊匹配:fuzzy
模糊查詢(Fuzzy Query)是 Elasticsearch 中一種近似匹配的搜索方式,用于查找與搜索詞項(xiàng)相似但不完全相等的文檔。基于編輯距離(Levenshtein 距離)計(jì)算兩個(gè)詞項(xiàng)之間的差異。
它通過(guò)允許最多的差異量來(lái)匹配文檔,以處理輸入錯(cuò)誤、拼寫錯(cuò)誤或輕微變體的情況。
用途:糾正拼寫錯(cuò)誤,模糊查詢可用于糾正用戶可能犯的拼寫錯(cuò)誤,可以提供寬松匹配,使搜索結(jié)果更加全面。
- 混淆字符 (box → fox)
- 缺少字符 (black → lack)
- 多出字符 (sic → sick)
- 顛倒次序 (act → cat)
請(qǐng)求示例:
GET /my_index/_search
{
"query": {
"fuzzy": {
"title": {
"value": "quick",
"fuzziness": "2"
}
}
}
}
fuzziness
是編輯距離,即:編輯成正確字符所需要挪動(dòng)的字符的數(shù)量
參數(shù)
- value:必須,關(guān)鍵詞。
-
fuzziness:編輯距離,范圍是(0,1,2),并非越大越好,過(guò)大召回率高但結(jié)果不準(zhǔn)確,默認(rèn)是:AUTO,即自動(dòng)從0~2取值。
- 兩段文本之間的Damerau-Levenshtein距離是使一個(gè)字符串與另一個(gè)字符串匹配所需的插入、刪除、替換和調(diào)換的數(shù)量。
- 距離公式:Levenshtein是lucene的概念,ES做了改進(jìn),使用的是基于Levenshtein的Damerau-Levenshtein,比如:axe=>aex。 Levenshtein會(huì)算作2個(gè)距離,而Damerau-Levenshtein只會(huì)算成1個(gè)距離。
- transpositions:可選,布爾值,指示編輯是否包括兩個(gè)相鄰字符的變位(ab→ba),默認(rèn)為true,使用的是Damerau-Levenshtein,如果為false,就會(huì)使用Levenshtein去計(jì)算。
短語(yǔ)前綴:match_phrase_prefix
先來(lái)了解下match_phrase,match_phrase檢索有如下特點(diǎn):
- match_phrase會(huì)分詞。
- 被檢索字段必須包含match_phrase中的所有詞項(xiàng)并且順序必須是相同的。
- 默認(rèn)被檢索字段包含的match_phrase中的詞項(xiàng)之間不能有其他詞項(xiàng)。
match_phrase_prefix
與match_phrase
相同,但是它多了一個(gè)特性,就是它允許在文本的最后一個(gè)詞項(xiàng)(term)上的前綴匹配。
如果是一個(gè)單詞,比如a,它會(huì)匹配文檔字段所有以a開(kāi)頭的文檔,如果是一個(gè)短語(yǔ),比如 “this is ma” ,他會(huì)先在倒排索引中做以ma做前綴搜索,然后在匹配到的doc中以 “this is” 做match_phrase查詢。
match_phrase_prefix
查詢是一種結(jié)合了短語(yǔ)匹配和前綴匹配的查詢方式。它用于在某個(gè)字段中匹配包含指定短語(yǔ)前綴的文檔。
具體來(lái)說(shuō),match_phrase_prefix
查詢會(huì)將查詢字符串分成兩部分:前綴部分和后綴部分。然后它會(huì)先對(duì)前綴部分進(jìn)行短語(yǔ)匹配,找到以該短語(yǔ)開(kāi)頭的文檔片段;接下來(lái),針對(duì)符合前綴匹配的文檔片段,再對(duì)后綴部分進(jìn)行前綴匹配,從而進(jìn)一步篩選出最終匹配的文檔。
以下是 match_phrase_prefix
查詢的示例:
GET /my_index/_search
{
"query": {
"match_phrase_prefix": {
"title": {
"query": "quick brown f",
"max_expansions": 10
}
}
}
}
解釋:
- 在上述示例中,我們執(zhí)行了一個(gè)
match_phrase_prefix
查詢。 - 查詢字段為
title
,我們要求匹配的短語(yǔ)是 “quick brown f”。 -
max_expansions
參數(shù)用于控制擴(kuò)展的前綴項(xiàng)數(shù)量(默認(rèn)為 50)。這里我們?cè)O(shè)置為 10,表示最多擴(kuò)展 10 個(gè)前綴項(xiàng)進(jìn)行匹配。
match_phrase_prefix
查詢適用于需要同時(shí)支持短語(yǔ)匹配和前綴匹配的場(chǎng)景。例如,當(dāng)用戶輸入一個(gè)搜索短語(yǔ)的前綴時(shí),可以使用該查詢來(lái)獲取相關(guān)的文檔結(jié)果。
參數(shù)
- analyzer:指定何種分析器來(lái)對(duì)該短語(yǔ)進(jìn)行分詞處理。
- max_expansions:限制匹配的最大詞項(xiàng),有點(diǎn)類似SQL中的limit,默認(rèn)值是50。
- boost:用于設(shè)置該查詢的權(quán)重。
- slop:允許短語(yǔ)間的詞項(xiàng)(term)間隔,slop 參數(shù)告訴 match_phrase 查詢?cè)~條相隔多遠(yuǎn)時(shí)仍然能將文檔視為匹配,相隔多遠(yuǎn)意思就是說(shuō)為了讓查詢和文檔匹配你需要移動(dòng)詞條多少次,默認(rèn)是0。
ngram & edge ngram
ngram 和 edge ngram 是兩種用于分析和索引文本的字符級(jí)別的分詞器。
- ngram:ngram 分詞器將輸入的文本按照指定的長(zhǎng)度切割成一系列連續(xù)的字符片段。例如,對(duì)于字符串 “Hello”,使用 2-gram(雙字符)分詞器會(huì)生成 [“He”, “el”, “l(fā)l”, “l(fā)o”]。
- edge ngram:edge ngram 分詞器是 ngram 分詞器的一種特殊形式,它只會(huì)產(chǎn)生從單詞開(kāi)頭開(kāi)始的 ngram 片段。例如,對(duì)于字符串 “Hello”,使用 2-gram(雙字符)edge ngram 分詞器會(huì)生成 [“He”, “el”]。 edge ngram作用類似fuzzy,但是性能要比f(wàn)uzzy好,當(dāng)然也更占用磁盤空間,原因是因?yàn)閑dge ngram對(duì)更細(xì)粒度的token創(chuàng)建了索引。
參數(shù):
- min_gram:創(chuàng)建索引所拆分字符的最小閾值。
- max_gram:創(chuàng)建索引所拆分字符的最大閾值。
以下是一個(gè)示例來(lái)說(shuō)明如何在 Elasticsearch 中使用 ngram 和 edge ngram 分詞器:
PUT /my_index
{
"settings": {
"analysis": {
"analyzer": {
"my_ngram_analyzer": {
"tokenizer": "my_ngram_tokenizer"
},
"my_edge_ngram_analyzer": {
"tokenizer": "my_edge_ngram_tokenizer"
}
},
"tokenizer": {
"my_ngram_tokenizer": {
"type": "ngram",
"min_gram": 2,
"max_gram": 4
},
"my_edge_ngram_tokenizer": {
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 10
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "my_ngram_analyzer"
},
"keyword": {
"type": "text",
"analyzer": "my_edge_ngram_analyzer"
}
}
}
}
在上述示例中,我們創(chuàng)建了一個(gè)名為 my_index
的索引,定義了兩個(gè)不同的分詞器和對(duì)應(yīng)的字段映射:
-
my_ngram_analyzer
使用了 ngram 分詞器,適用于處理title
字段。 -
my_edge_ngram_analyzer
使用了 edge ngram 分詞器,適用于處理keyword
字段。
通過(guò)在查詢時(shí)指定相應(yīng)的分析器,可以使用這些分詞器來(lái)進(jìn)行文本搜索、前綴搜索等操作。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-791289.html
注意:ngram 作為 tokenizer 的時(shí)候會(huì)把空格也包含在內(nèi),而作為 token filter 時(shí),空格不會(huì)作為處理字符。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-791289.html
到了這里,關(guān)于一起學(xué)Elasticsearch系列-模糊搜索的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!