前面為大家介紹了:【ES系列06:ik分詞+Full text queries 之match query枫慷、ES系列07:match_phrase與match_phrase_prefix query】饺窿。今天TeHero為大家分享 Full text queries 剩余的4種查詢語(yǔ)句multi_match query尾膊、common terms query、query_string query灰瞻、simple_query_string query丧叽,同時(shí)結(jié)合倒排序索引原理翁巍,將DSL語(yǔ)句轉(zhuǎn)化為sql語(yǔ)句,方便大家理解學(xué)習(xí)慌植。
ps:文章最后有關(guān)于 Full text queries 所有查詢的總結(jié)甚牲!
原文鏈接:【排版好看點(diǎn)】ES系列08:Full text queries(3) query_string系列
?
Full Text queries 系列知識(shí)腦圖
ps:上圖的xmind文件獲取方式見(jiàn)評(píng)論區(qū)!
在學(xué)習(xí)本節(jié)之前蝶柿,請(qǐng)先參考:ES系列07:match_phrase與match_phrase_prefix query丈钙,完成數(shù)據(jù)導(dǎo)入和倒排列表的創(chuàng)建。
?
ps:如果看不懂上圖交汤,請(qǐng)先閱讀學(xué)習(xí):ElasticSearch系列05:倒排序索引與分詞Analysis
一雏赦、multi_match query -match 的多字段版本
結(jié)合之間的match語(yǔ)法,這個(gè)是很好理解的:ES系列06:ik分詞+Full text queries 之match query
# 1芙扎、同時(shí)查詢 "content", "content.ik_smart_analyzer"喉誊,得到文檔3
GET /tehero_index/_doc/_search
{
"query": {
"multi_match": {
"query": "系統(tǒng)",
"fields": [
"content",
"content.ik_smart_analyzer"
]
}
}
}
# 2、同時(shí)查詢 所有字段 得到所有文檔
GET /tehero_index/_doc/_search
{
"query": {
"multi_match": {
"query": "系統(tǒng)",
"fields": [
"content",
"content.ik_smart_analyzer",
"content.ik_max_analyzer"
]
}
}
}
需要注意的是纵顾,多個(gè)Fields之間的查詢關(guān)系是 or 伍茄,就相當(dāng)于mysql 的 【where 字段1=“檢索詞”or 字段2 = “檢索詞” or 字段3 = “檢索詞”】
字段^數(shù)字:表示增強(qiáng)該字段(權(quán)重影響相關(guān)性評(píng)分):先知道有這么個(gè)屬性即可,相關(guān)性評(píng)分是一個(gè)重點(diǎn)和難點(diǎn)施逾,后面再系統(tǒng)講解敷矫。
GET /tehero_index/_doc/_search
{
"query": {
"multi_match": {
"query": "系統(tǒng)",
"fields": [
"content",
"content.ik_smart_analyzer^3",
"content.ik_max_analyzer"
]
}
}
}
1.1 multi_match query 對(duì)應(yīng)的sql語(yǔ)句
ET /tehero_index/_doc/_search
{
"query": {
"multi_match": {
"query": "系統(tǒng)學(xué)",
"fields": [
"content.ik_smart_analyzer",
"content.ik_max_analyzer"
]
}
}
}
DSL執(zhí)行分析:
1)檢索關(guān)鍵詞“系統(tǒng)學(xué)”,根據(jù)搜索的field對(duì)應(yīng)的分詞器汉额,進(jìn)行不同的分詞: "content.ik_smart_analyzer"字段(簡(jiǎn)稱field1)分詞曹仗,得到一個(gè)Token【系統(tǒng)學(xué)】;"content.ik_max_analyzer"字段(簡(jiǎn)稱field2)分詞蠕搜,得到三個(gè)Token【系統(tǒng)學(xué)怎茫,系統(tǒng),學(xué)】妓灌。
2)使用檢索詞的Token在對(duì)應(yīng)的field的PostingList中進(jìn)行檢索轨蛤,等價(jià)于sql語(yǔ)句:【select id from field1-PostingList where Token = “系統(tǒng)學(xué)”】【select id from field2-PostingList where Token in ("系統(tǒng)學(xué)","系統(tǒng)"虫埂,"學(xué)")】祥山;
3)最后再對(duì)檢索出來(lái)的兩個(gè) PostingList 做一個(gè)合并操作,得到文檔掉伏。
二缝呕、common terms query——對(duì)停頓詞的檢索優(yōu)化(簡(jiǎn)單了解即可)
對(duì)于這個(gè)語(yǔ)法澳窑,先了解即可,主要還是用于英語(yǔ)供常,對(duì)于中文摊聋,實(shí)用性不大。(ps:以下內(nèi)容翻譯至官網(wǎng)) 該查詢將檢索詞分割分為兩組:更重要(即低頻率而言)和不太重要的(即栈暇,高頻率而言栗精,如已停用詞)。首先瞻鹏,它搜索與更重要的術(shù)語(yǔ)匹配的文檔悲立。這些術(shù)語(yǔ)出現(xiàn)在較少的文檔中,并且對(duì)相關(guān)性具有更大的影響新博。然后薪夕,它對(duì)不那么重要的詞執(zhí)行第二次查詢,這些詞經(jīng)常出現(xiàn)并且對(duì)相關(guān)性影響很小赫悄。但是原献,它是在第一個(gè)查詢的結(jié)果集基礎(chǔ)上,而不是計(jì)算所有匹配文檔的相關(guān)性得分埂淮。這樣姑隅,高頻項(xiàng)可以改善相關(guān)性計(jì)算,而無(wú)需付出性能不佳的代價(jià)倔撞。如果查詢僅由高頻詞組成讲仰,則將單個(gè)查詢作為AND(合并)查詢執(zhí)行,換句話說(shuō)痪蝇,所有詞都是必需的鄙陡。
# 文檔頻率大于0.1%的單詞(例如"this"和"is")將被視為通用術(shù)語(yǔ)。
GET /_search
{
"query": {
"common": {
"body": {
"query": "nelly the elephant as a cartoon",
"cutoff_frequency": 0.001,
"low_freq_operator": "and"
}
}
}
}
等價(jià)于:
GET /_search
{
"query": {
"bool": {
"must": [
{ "term": { "body": "nelly"}},
{ "term": { "body": "elephant"}},
{ "term": { "body": "cartoon"}}
],
"should": [
{ "term": { "body": "the"}},
{ "term": { "body": "as"}},
{ "term": { "body": "a"}}
]
}
}
}
總結(jié):common terms query 目的:在保證檢索性能的前提下躏啰,提高搜索結(jié)果的準(zhǔn)確度趁矾。(能檢索到the a 等高頻率的停頓詞)
# 簡(jiǎn)單理解,對(duì) the a as 等進(jìn)行分詞
GET /_analyze
{
"text": ["the a as"],
"analyzer": "ik_max_word"
}
結(jié)果:為空给僵,因?yàn)檫@些停頓詞都被過(guò)濾掉了毫捣,這個(gè)時(shí)候就使用 common terms query,檢索到這些詞
{
"tokens": []
}
三帝际、query_string query
允許我們?cè)趩蝹€(gè)查詢字符串中指定AND | OR | NOT條件蔓同,同時(shí)也和 multi_match query 一樣,支持多字段搜索胡本。
# 1牌柄、檢索同時(shí)包含Token【系統(tǒng)學(xué)、es】的文檔侧甫,結(jié)果為空
GET /tehero_index/_doc/_search
{
"query": {
"query_string" : {
"fields" : ["content.ik_smart_analyzer"],
"query" : "系統(tǒng)學(xué) AND es"
}
}
}
# 2珊佣、檢索包含Token【系統(tǒng)學(xué)、es】二者之一的文檔披粟,能檢索到文檔1咒锻、2、4
GET /tehero_index/_doc/_search
{
"query": {
"query_string" : {
"fields" : ["content.ik_smart_analyzer"],
"query" : "系統(tǒng)學(xué) OR es"
}
}
}
有了前面的基礎(chǔ)守屉,query_string query是非常容易理解的惑艇,語(yǔ)句1等價(jià)于sql語(yǔ)句【where Token = “系統(tǒng)學(xué)”and Token = “es” 】
注意點(diǎn):1、中間的連接詞【AND | OR | NOT】必須是全大寫拇泛;
2滨巴、各個(gè)檢索詞依然會(huì)被對(duì)應(yīng)的分詞器分詞,單個(gè)檢索詞就相當(dāng)于match query俺叭。
GET /tehero_index/_doc/_search
{
"query": {
"query_string" : {
"fields" : ["content.ik_smart_analyzer"],
"query" : "系統(tǒng)編程 OR es"
}
}
}
就比如上例恭取,單個(gè)檢索詞“系統(tǒng)編程”還是會(huì)被分詞器“ik_smart”分詞為兩個(gè)Token【系統(tǒng)、編程】熄守,同時(shí)對(duì)這個(gè)檢索詞“系統(tǒng)編程”執(zhí)行 match query查詢蜈垮,所以上面的DSL會(huì)把所有的文檔都檢索出來(lái)。
四裕照、simple_query_string query
類似于query_string 攒发,但是會(huì)忽略錯(cuò)誤的語(yǔ)法,永遠(yuǎn)不會(huì)引發(fā)異常晋南,并且會(huì)丟棄查詢的無(wú)效部分惠猿。
simple_query_string支持以下特殊字符: + 表示與運(yùn)算,相當(dāng)于query_string 的 AND | 表示或運(yùn)算负间,相當(dāng)于query_string 的 OR - 取反單個(gè)令牌,相當(dāng)于query_string 的 NOT "" 表示對(duì)檢索詞進(jìn)行 match_phrase query * 字詞末尾表示前綴查詢
結(jié)合DSL語(yǔ)句簡(jiǎn)單理解下:
4.1 + 表示與運(yùn)算紊扬,相當(dāng)于query_string 的 AND
# 1、檢索到文檔4 GET /tehero_index/_doc/_search { "query": { "simple_query_string" : { "fields" : ["content.ik_smart_analyzer"], "query" : "系統(tǒng)學(xué) + 間隔" } } }
4.2 | 表示或運(yùn)算唉擂,相當(dāng)于query_string 的 OR
# 2餐屎、檢索到文檔1、2玩祟、4 GET /tehero_index/_doc/_search { "query": { "simple_query_string" : { "fields" : ["content.ik_smart_analyzer"], "query" : "系統(tǒng)學(xué) | 間隔" } } }
4.3 - 取反單個(gè)令牌,相當(dāng)于query_string 的 NOT
# 3腹缩、檢索到文檔1、2 GET /tehero_index/_doc/_search { "query": { "simple_query_string" : { "fields" : ["content.ik_smart_analyzer"], "query" : "系統(tǒng)學(xué) -間隔", "default_operator": "and" } } }
注意:參數(shù)"default_operator": "and"空扎。該參數(shù)的默認(rèn)值為or藏鹊。 上述DSL對(duì)應(yīng)的sql語(yǔ)句為:【where Token = 系統(tǒng)學(xué) and Token <> 間隔】
4.4 "" 表示對(duì)檢索詞進(jìn)行 match_phrase query
# 4、檢索到文檔2 GET /tehero_index/_doc/_search { "query": { "simple_query_string" : { "fields" : ["content.ik_smart_analyzer"], "query" : "\"系統(tǒng)學(xué)編程關(guān)注\"" } } } # 5转锈、檢索到所有文檔 GET /tehero_index/_doc/_search { "query": { "simple_query_string" : { "fields" : ["content.ik_smart_analyzer"], "query" : "系統(tǒng)學(xué)編程關(guān)注" } } }
分析:"query" : ""系統(tǒng)學(xué)編程關(guān)注""盘寡,會(huì)對(duì)檢索詞執(zhí)行 match_phrase query !
4.5 * 字詞末尾表示前綴查詢 -match_phrase_prefix query
# 6撮慨、檢索到文檔 3 GET /tehero_index/_doc/_search { "query": { "simple_query_string" : { "fields" : ["content.ik_smart_analyzer"], "query" : "系統(tǒng)" } } } # 6竿痰、檢索到所有文檔脆粥,等價(jià)于match_phrase_prefix query GET /tehero_index/_doc/_search { "query": { "simple_query_string" : { "fields" : ["content.ik_smart_analyzer"], "query" : "系統(tǒng)*" } } }
五、總結(jié)
到此影涉,我們已經(jīng)學(xué)完了 Full text queries 所有的查詢語(yǔ)句:
1)match query:用于執(zhí)行全文查詢的標(biāo)準(zhǔn)查詢变隔,包括模糊匹配和短語(yǔ)或接近查詢。重要參數(shù):控制Token之間的布爾關(guān)系:operator:or/and
2)match_phrase query:與match查詢類似蟹倾,但用于匹配確切的短語(yǔ)或單詞接近匹配匣缘。重要參數(shù):Token之間的位置距離:slop 參數(shù)
3)match_phrase_prefix query:與match_phrase查詢類似,但是會(huì)對(duì)最后一個(gè)Token在倒排序索引列表中進(jìn)行通配符搜索鲜棠。重要參數(shù):模糊匹配數(shù)控制:max_expansions 默認(rèn)值50肌厨,最小值為1
4)multi_match query:match查詢 的多字段版本。該查詢?cè)趯?shí)際中使用較多豁陆,可以降低DSL語(yǔ)句的復(fù)雜性柑爸。同時(shí)該語(yǔ)句有多個(gè)查詢類型,后面TeHero會(huì)專門進(jìn)行講解献联。
5)common terms query:對(duì)于中文檢索意義不大竖配。
6)query_string query 和 simple_query_string query,其實(shí)就是以上 query語(yǔ)句的合集里逆,使用非常靈活进胯,DSL編寫簡(jiǎn)單。但是原押,TeHero認(rèn)為這兩個(gè)查詢語(yǔ)句胁镐,有一個(gè)很明顯的弊端:類似于sql注入。如果用戶在檢索詞輸入了對(duì)應(yīng)的“關(guān)鍵字”【比如OR诸衔、】等盯漂,用戶將獲取到本不應(yīng)該被查詢到的數(shù)據(jù)。慎用笨农!*
下期預(yù)告:Term-level queries(精確匹配)
●ElasticSearch系列01:如何系統(tǒng)學(xué)習(xí)ES
●ES系列05:倒排序索引與分詞Analysis