一文搞懂match、match_phrase與match_phrase_prefix的檢索過程

一、在開始之前,完成數據準備:

# 創建映射
PUT /tehero_index
{"settings": {"index": {"number_of_shards": 1,"number_of_replicas": 1}},"mappings": {"_doc": {"dynamic": false,"properties": {"id": {"type": "integer"},"content": {"type": "keyword","fields": {"ik_max_analyzer": {"type": "text","analyzer": "ik_max_word","search_analyzer": "ik_max_word"},"ik_smart_analyzer": {"type": "text","analyzer": "ik_smart"}}},"name":{"type":"text"},"createAt": {"type": "date"}}}}
}
# 導入測試數據
POST _bulk
{ "index" : { "_index" : "tehero_index", "_type" : "_doc", "_id" : "1" } }
{ "id" : 1,"content":"關注我,系統學編程" }
{ "index" : { "_index" : "tehero_index", "_type" : "_doc", "_id" : "2" } }
{ "id" : 2,"content":"系統學編程,關注我" }
{ "index" : { "_index" : "tehero_index", "_type" : "_doc", "_id" : "3" } }
{ "id" : 3,"content":"系統編程,關注我" }
{ "index" : { "_index" : "tehero_index", "_type" : "_doc", "_id" : "4" } }
{ "id" : 4,"content":"關注我,間隔系統學編程" }

二、根據ik_smart分詞和content字段建立倒排序索引

原始數據:

{ "id" : 1,"content":"關注我,系統學編程" }
{ "id" : 2,"content":"系統學編程,關注我" }
{ "id" : 3,"content":"系統編程,關注我" }
{ "id" : 4,"content":"關注我,間隔系統學編程" }

ps:如果看不懂上圖,請先閱讀學習:ElasticSearch系列05:倒排序索引與分詞Analysis

三、match query 對應到mysql

昨天有小伙伴反饋說,match query 的實例寫得太枯燥,建議和mysql對比講解,今天它來了!
# DSL 語句
GET /tehero_index/_doc/_search
{"query":{"match":{"content.ik_smart_analyzer":"系統編程"}}
}

DSL執行步驟分析:

  • 1)檢索詞“系統編程”被ik_smart分詞器分詞為兩個Token【系統】【編程】;
  • 2)將這兩個Token在【倒排索引】中,針對Token字段進行檢索,等價于sql:【where Token = 系統 or Token = 編程】;
  • 3)對照圖【數據的倒排序索引】,可見,該DSL能檢索到所有文檔,文檔3的評分最高(因為它包含兩個Token),其他3個文檔評分相同。
有了對應到mysql 的例子,我想大家對match query 這個查詢語句,就應該有一個很好的理解。那么接下來,開始學習今天的新知識: match_phrase query 和match_phrase_prefix query

四、match_phrase query

match_phrase查詢分 析文本并根據分析的文本創建一個短語查詢。match_phrase? 會將檢索關鍵詞分詞。match_phrase的分詞結果必 須在被檢索字段的分詞中都包含,而且 順序必須相同,而且 默認必須都是連續的。

簡單看個例子,與match query 對比下,就很好理解了:

使用 match_phrase 查詢:

# 使用match_phrase查詢,ik_smart分詞
GET /tehero_index/_doc/_search
{"query": {"match_phrase": {"content.ik_smart_analyzer": {"query": "關注我,系統學"}}}
}# 結果:只有文檔1
{"took": 1,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 0.7370664,"hits": [{"_index": "tehero_index","_type": "_doc","_id": "1","_score": 0.7370664,"_source": {"id": 1,"content": "關注我,系統學編程"}}]}
}

使用 match 查詢:

# 使用match查詢,ik_smart分詞
GET /tehero_index/_doc/_search
{"query": {"match": {"content.ik_smart_analyzer": {"query": "關注我,系統學"}}}
}
# 可以查詢出所有結果
分析:上面的例子使用的 分詞器是ik_smart,所以 檢索詞“關注我,系統學”會被分詞為3個Token【關注、我、系統學】;而文檔1、文檔2和文檔4 的content被分詞后 都包含這3個關鍵詞,但是 只有文檔1的Token的順序和檢索詞一致,且連續。所以使用 match_phrase 查詢 只能查詢到文檔1(ps:文檔2 Token順序不一致;文檔4 Token不連續;文檔3 Token沒有完全包含)。 使用 match查詢可以查詢到所有文檔,是因為所有文檔 都有【關注、我】這兩個Token
  • 4.1 match_phrase 核心參數:slop 參數-Token之間的位置距離容差值
# 將上面的 match_phrase 查詢新增一個 slop參數
GET /tehero_index/_doc/_search
{"query": {"match_phrase": {"content.ik_smart_analyzer": {"query": "關注我,系統學","slop":1}}}
}
# 結果:文檔1和文檔4都被檢索出來
分析:使用 analyze 接口 分析下文檔4的Token
# 文檔4 content 的分詞
GET /_analyze
{"text": ["關注我,間隔系統學編程"],"analyzer": "ik_smart"
}
# 結果
{"tokens": [{"token": "關注","start_offset": 0,"end_offset": 2,"type": "CN_WORD","position": 0},{"token": "我","start_offset": 2,"end_offset": 3,"type": "CN_CHAR","position": 1},{"token": "間隔","start_offset": 4,"end_offset": 6,"type": "CN_WORD","position": 2},{"token": "系統學","start_offset": 6,"end_offset": 9,"type": "CN_WORD","position": 3},{"token": "編程","start_offset": 9,"end_offset": 11,"type": "CN_WORD","position": 4}]
}
通過分詞測試,發現Token【我】與【系統學】的 position差值為1(等于slop的值 )所以文檔4也被檢索出來了。

ps:如果沒看明白,那就來看下match_phrase query對應到mysql是怎樣的吧!

  • 4.2match_phrase query對應到mysql
# DSL語句
GET /tehero_index/_doc/_search
{"query":{"match_phrase":{"content.ik_smart_analyzer":"系統編程"}}
}

DSL執行步驟分析:

  • 1)檢索詞“系統編程”被分詞為兩個Token【系統,Position=0】【編程,Position=1】;
  • 2)倒排索引檢索時,等價于sql:【where Token = 系統 and?系統_Position=0?and Token = 編程 and?編程_Position=1】;
  • 3)對照圖【數據的倒排序索引】,只有文檔3滿足條件,所以該DSL語句只能查詢到文檔3。

五、match_phrase_prefix query

與match_phrase查詢類似,但是 會對最后一個Token在倒排序索引列表中進行通配符搜索。Token的模糊匹配數控制: max_expansions 默認值為50。我們使用 content.ik_smart_analyzer?這個字段中的 【系統學】(文檔1、2、4 包含)和 【系統】(文檔3包含)這 兩個Token來講解match_phraseprefix 的用法:(因為 使用的是ik_smart分詞器,所以【系統學】就只能被分詞為一個Token)
# 1、先使用match_phrase查詢,沒有結果
GET tehero_index/_doc/_search
{"query": {"match_phrase": {"content.ik_smart_analyzer": {"query": "系"}}}
}# 2、使用match_phrase_prefix查詢, "max_expansions": 1,得到文檔3
GET tehero_index/_doc/_search
{"query": {"match_phrase_prefix": {"content.ik_smart_analyzer": {"query": "系","max_expansions": 1}}}
}# 3、使用match_phrase_prefix查詢, "max_expansions": 2,得到所有文檔
GET tehero_index/_doc/_search
{"query": {"match_phrase_prefix": {"content.ik_smart_analyzer": {"query": "系","max_expansions": 2}}}
}
結果分析:【語句1】查不到結果,是因為 根據ik_smart分詞器生成的倒排序索引中,所有文檔中都 不包含Token【系】;【語句2】查詢到文檔3,是因為 文檔3包含Token【系統】,同時?"max_expansions": 1,所以 檢索關鍵詞【系】+ 1個通配符匹配,就可以匹配到 一個Token【系統】;【語句3】查詢到所有文檔,是因為"max_expansions": 2,所以 檢索關鍵詞【系】+ 2個通配符匹配,就可以匹配到 兩個Token【系統、系統學】,所以就可以查詢到所有。回憶下,之前所講的es倒排序索引原理: 先分詞創建倒排序索引,再檢索倒排序索引得到文檔,就很好理解了

注意:"max_expansions"的值最小為1哪怕你設置為0,依然會 + 1個通配符匹配;所以,盡量不要用該語句,因為,最后一個Token始終要去掃描大量的索引性能可能會很差。

  • 5.1 match_phrase_prefix query 對應到mysql
GET tehero_index/_doc/_search
{"query": {"match_phrase_prefix": {"content.ik_smart_analyzer": {"query": "系","max_expansions": 1}}}
}

DSL執行步驟分析:

  • 1)檢索詞“系”被分詞為一個個Token【系】+ 1個通配符;
  • 2)倒排索引檢索時,等價于sql:【where Token = 系 or Token?like “系_”】;
  • 3)對照圖【數據的倒排序索引】,只有文檔3滿足條件包含Token【系統】,所以該DSL語句只能查詢到文檔3。

六、總結

到此,我們已經學習了 Full text queries最常用的3種查詢:

1)match query:用于執行全文查詢的標準查詢,包括 模糊匹配和短語或接近查詢。重要參數:控制Token之間的布爾關系:operator:or/and
2)match_phrase query:與match查詢類似, 但用于匹配確切的短語或單詞接近匹配。重要參數:Token之間的位置距離:slop 參數
3)match_phrase_prefix query:與match_phrase查詢類似,但是會 對最后一個Token在倒排序索引列表中進行通配符搜索。重要參數:模糊匹配數控制:max_expansions 默認值50,最小值為1

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696238.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696238.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696238.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

探索氣膜球幕影院:未來的電影體驗

氣膜球幕影院作為一種新興的電影放映方式,正逐漸成為人們關注的焦點。它采用了充氣式膜結構,可以為觀眾帶來 360 度全景的觀影體驗,讓人仿佛置身于電影之中。本文將介紹氣膜球幕影院的特點、技術原理以及未來的發展前景。 傳說在古代&#x…

Linux系統運維命令:使用 tail,grep組合命令(包括wc,sort,awk,sed等),可以方便的查閱和操作正在改變的日志文件的具體內容

一、命令介紹 1、tail命令 tail命令是Linux系統中常用的命令之一,用于查看文件的末尾內容。它具有許多有用的選項,可以幫助用戶輕松地查找并顯示文件中的信息。 它默認顯示文件的最后10行,但可以通過各種選項來定制輸出的行數、字節數等。ta…

十四、圖像幾何形狀繪制

項目功能實現&#xff1a;矩形、圓形、橢圓等幾何形狀繪制&#xff0c;并與原圖進行相應比例融合 按照之前的博文結構來&#xff0c;這里就不在贅述了 一、頭文件 drawing.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class DRAWING { public:void…

Python筆記-super().init(root)的作用

假設我們有一個名為Animal的父類&#xff0c;它有一個屬性color&#xff0c;在其構造函數__init__中被初始化&#xff1a; class Animal:def __init__(self, color):self.color color現在&#xff0c;我們想創建一個Animal的子類&#xff0c;名為Dog。Dog類有自己的屬性name&…

QPaint繪制自定義儀表盤組件01

網上抄別人的&#xff0c;只是放這里自己看一下&#xff0c;看完就刪掉 ui Dashboard.pro QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomm…

【xss跨站漏洞】xss漏洞前置知識點整理

xss漏洞成因 xss漏洞是一種前端javascript產生的漏洞。 我們網站基本都是會用到javascript編寫一些東西&#xff0c;瀏覽器也能直接識別javascript。 如果有一個地方能夠輸入文字&#xff0c;但是他又沒有過濾你的輸入&#xff0c;那么自己或者他人看到你輸入的javascript代…

JVM知識——安全點

安全點是JVM要準備進行垃圾回收時&#xff0c;選定一些特定的位置&#xff0c;當應用程序線程執行到這些位置時&#xff0c;安全的先暫停下來&#xff0c;以便JVM執行GC線程進行垃圾回收。 JVM在字節碼指令中會選取一些指令作為安全點&#xff0c;安全點的選取一般是循環結束、…

課時42:表達式_運算符_bc計算

3.1.5 bc計算 學習目標 這一節&#xff0c;我們從 基礎知識、簡單實踐、小結 三個方面來學習。 基礎知識 簡介 bc是一種任意精度的計算語言&#xff0c;提供了語法結構&#xff0c;比如條件判斷、循環等&#xff0c;功能是很強大的&#xff0c;還能進行進制轉換。常見參數-…

week04day02(爬蟲02)

<span>: 通常用于對文本的一部分進行樣式設置或腳本操作。<a>: 定義超鏈接&#xff0c;用于創建鏈接到其他頁面或資源的文本。<img>: 用于插入圖像。<br>: 用于插入換行。 姓名&#xff1a;<input type"text" value"lisi">…

嵌入式培訓機構四個月實訓課程筆記(完整版)-Linux ARM驅動編程第七天-內核函數接口(物聯技術666)

鏈接&#xff1a;https://pan.baidu.com/s/1V0E9IHSoLbpiWJsncmFgdA?pwd1688 提取碼&#xff1a;1688 //************************************************** #include <linux/module.h> /*module_init()*/ #include <linux/kernel.h> /* printk() *…

【析】考慮同時取送和時間窗的車輛路徑及求解算法

期刊&#xff1a;computer engineering and applications 計算機工程與應用![c 引言 1. 問題分析 1.1 問題描述 問題描述為&#xff1a; 若干運輸車輛從配送中心出發為客戶取送貨并最終返回配送中心&#xff0c;每位客戶僅由一輛車服務一次&#xff0c;車輛在配送過程中任…

rust實戰系列八:常量

在Rust中還可以用const關鍵字做聲明。如下所示: const GLOBAL: i32 0; 使用const聲明的是常量&#xff0c;而不是變量。因此一定不允許使用mut關鍵字修飾這 個變量綁定&#xff0c;這是語法錯誤。常量的初始化表達式也一定要是一個編譯期常量&#xff0c;不 能是運行期的值。它…

ChatGPT丨成像光譜遙感技術中的AI革命:ChatGPT應用指南

遙感技術主要通過衛星和飛機從遠處觀察和測量我們的環境&#xff0c;是理解和監測地球物理、化學和生物系統的基石。ChatGPT是由OpenAI開發的最先進的語言模型&#xff0c;在理解和生成人類語言方面表現出了非凡的能力。本課程重點介紹ChatGPT在遙感中的應用&#xff0c;人工智…

尾礦庫排洪系統結構仿真軟件WKStruc(可試用)

1、背景介紹 尾礦庫作為重大危險源之一&#xff0c;在國際災害事故排名中位列第18位&#xff0c;根據中國鉬業2019年8月刊《中國尾礦庫潰壩與泄漏事故統計及成因分析》的統計&#xff0c;在46起尾礦庫泄漏事故中&#xff0c;由于排洪設施導致的尾礦泄漏事故占比高達1/3&#x…

c#創建安裝windows服務

背景:最近在做設備數據對接采集時,遇到一些設備不是標準的Service-Client接口,導致采集的數據不夠準確;比如設備如果中途開關機后,加工的數量就會從0開始重新計數,因此需要實時監控設備的數據,進行疊加處理;考略到工廠設備比較多,實時監聽接口的數據為每秒3次,因此將…

外包干了三年,技術算是廢了。。。

先說一下自己的個人情況&#xff0c;大專生&#xff0c;17年通過校招進入湖南某軟件公司&#xff0c;干了接近5年的手工測試&#xff0c;今年年初&#xff0c;感覺自己不能夠在這樣下去了&#xff0c;長時間呆在一個舒適的環境會讓一個人墮落!而我已經在一個企業干了五年的手工…

LeetCode.106. 從中序與后序遍歷序列構造二叉樹

題目 106. 從中序與后序遍歷序列構造二叉樹 分析 前面講過根據前序和中序構建二叉樹&#xff1a;博客鏈接 這道題是告訴我們一顆二叉樹的后序和中序&#xff0c;讓我們根據后序和中序構造出整顆二叉樹。 拿到這道題&#xff0c;我們首先要知道中序的后序又怎樣的性質&#…

云上業務一鍵性能調優,應用程序性能診斷工具 Btune 上線

- 01 - 終于等來了預算&#xff0c;這就把服務遷移到最新的 CPU 平臺上去&#xff0c;這樣前端的同事立馬就能感受我們帶來的速度提升了。可是…… 這些性能指標怎么回事&#xff1f;不僅沒有全面提升&#xff0c;有些反而下降了。不應該這樣啊&#xff0c;這可怎么辦&#xf…

使用單一ASM-HEMT模型實現從X波段到Ka波段精確的GaN HEMT非線性仿真

來源&#xff1a;Accurate Nonlinear GaN HEMT Simulations from X- to Ka-Band using a Single ASM-HEMT Model 摘要&#xff1a;本文首次研究了ASM-HEMT模型在寬頻帶范圍內的大信號準確性。在10、20和30 GHz的頻率下&#xff0c;通過測量和模擬功率掃描進行了比較。在相同的頻…

day05-進程通信

1> 將互斥機制的代碼實現重新敲一遍 代碼&#xff1a; #include<myhead.h>int num520;//臨界資源//1.創建互斥鎖 pthread_mutex_t fastmutex;//定義任務函數 void *task1(void *arg){printf("1111111\n");//3.臨界區上面獲取鎖資源&#xff08;上鎖&#…