ES匹配查詢

2021-10-09 20:33:25 字數 3627 閱讀 6593

,

"full_text":}

}put my_index/my_type/1

索引中keyword和text兩種不同的資料型別,我來看看兩個字段分別在倒排索引中的建立索引的方式。

keyword:exact_value欄位]}

text:full_text欄位,]

}由於keyword型別字段不會經過分析器處理,exact_value在倒排索引中以[hello wrold!]的完整形式建立索引;text型別經過分析器處理,分析器會將內容進行字元過濾、分詞、大小寫轉換等操作,full_text欄位在倒排索引中拆分為[hello、world]兩個單詞元素形式建立索引。

term query

對上述寫入索引的文件,使用term查詢方式,我們來看看效果

1、get my_index/my_type/_search}}

2、get my_index/my_type/_search}}

3、get my_index/my_type/_search}}

4、get my_index/my_type/_search

}}

查詢結果:

1、查詢成功,因為exact_value欄位索引中包含完整的內容hello world!。

2、查詢失敗,因為full_text欄位索引中只包含hello和world這兩個詞。 它不包含完整的字串hello world !。

3、查詢成功,詞語world匹配full_text的索引單詞。

4、查詢失敗,必須精確匹配world單詞,大小寫區分導致無法搜尋成功。

所以,很明顯term查詢是一種精確的匹配模式,只有當與倒排索引中的元素完全匹配時,返回結果。

基於全文

基於全文的查詢是更高階的查詢方式,它首先會了解字段對映的資訊。如果查詢乙個未經過分析的keyword型別字段,它會將整個查詢字串作為單個詞項對待;如果要查詢乙個已分析的text型別字段,它也會先將查詢字串傳遞到乙個到分析器,然後生成乙個供查詢的詞項列表,一旦組成了詞項列表,這個查詢會對每個詞項逐一執行底層的查詢,再將結果合併返回。

基於全文的查詢我們以match query為具體案例分析,可以發現它與term query的區別。

match query

還是以上例中建立的文件,將term查詢改為match查詢方式:

1、get my_index/my_type/_search}}

2、get my_index/my_type/_search}}

3、get my_index/my_type/_search}}

4、get my_index/my_type/_search

}}

查詢結果:

1、查詢成功,因為exact_value欄位索引中包含完整的內容hello world!。

2、查詢成功,因為full_text欄位在建立倒排索引時經過了分析器處理,match查詢也會將輸入查詢的內容經過分析器處理,所以查詢匹配成功。

3、查詢成功,詞語world匹配full_text的索引單詞。

4、查詢成功,match查詢結果分析器處理後也會對大小寫字元進行過濾,因此匹配成功。

由上結果可以發現,相對term而言,match 會是更靈活合適的一種查詢方式,它是乙個高階全文查詢 ,既能處理全文本段,又能處理精確字段。

match phrase query

match query有乙個特點,能夠提供單個或多個元素的搜尋,但它並不關心元素在文字中的順序,如果我們需要一種嚴格的順序查詢方式,這時就可以用到match phrase(短語匹配)查詢了,它對查詢條件中的語句,要求所有的元素都出現在倒排中,並且連續且順序一致的排列(分詞時,es已對每個元素標記乙個位置以便排序)。

例如:

```bash

1、get my_index/my_type/_search}}

2、get my_index/my_type/_search}}

3、get my_index/my_type/_search}}

}

查詢結果:

1、查詢成功。

2、查詢失敗,因為單詞順序不匹配。

3、查詢成功,match query並不關心單詞順序。

部分匹配

上面介紹的所有查詢都是針對整個詞的操作,只能查詢倒排索引中存在的詞,最小的單元為單個詞。為了提供更靈活的匹配方式,es也允許使用者指定查詢詞的一部分,並找出所有包含這部分片段的詞。類似於sql中的like 「%abc%」的匹配效果。

prefix query

它假定傳入字首就正是要查詢的字首,語句例子如下:

```bash

get my_index/my_type/_search

}}前

綴匹配的執行順序:

1、掃瞄詞列表並查詢到第乙個以「hel」開始的詞。

2、蒐集關聯的文件 id 。

3、移動到下乙個詞。

4、如果這個詞也是以「hel」開頭,查詢跳回到第二步再重複執行,直到所有索引掃瞄完畢。

wildcard query

匹配索引元素中包含字元內容的文件。另外,它也可以使用標準的 shell 萬用字元查詢: ? 匹配任意字元, * 匹配 0個 或多個字元。一般為了防止極慢的萬用字元查詢,萬用字元術語不應以萬用字元*或?之一開頭。其匹配的執行順序與字首匹配相似,語句例子如下:

get /_search

}}

regexp query

匹配索引元素中滿足正規表示式的文件。一般正規表示式對該查詢方式的效能也會有很大影響,像[ .* ?+]這樣的萬用字元匹配器會降低效能。其匹配的執行順序與字首匹配相似,語句例子如下:

get /_search

}}

這三種方式都是基於詞項查詢,它們也需要遍歷倒排索引中的詞條列表來找到所有的匹配詞條,然後逐個詞條地收集對應的文件id。像wildcard query和regexp query的匹配模式靈活多變,但也更為複雜,很有可能需要對中的逐個字元進行嚴格匹配,會降低查詢效能。

業務場景及使用

我們系統的字段內容中主要有兩種資料格式,一種為引數值(如pageid=zzzz),另一種為json串形式的自定義引數(如param= )。針對前者,業務一般在搜尋時會精確知道字段值,我們會對字段設定為keyword的型別,省去在寫入時分析步驟,不做索引的分詞處理,會明顯提公升寫入效率和節省儲存空間;針對後者,json格式不好直接表達,就需要提供模糊搜尋的功能,我們會對字段設定為text的型別。

一開始為提供最全面的搜尋方式,系統使用wildcard query以支援字元匹配級別的模糊查詢,但系統在查詢自定義引數等大字段耗時很長,甚至查詢超時,導致使用者體驗不佳。因此系統剔除了部分字元匹配功能,對keyword欄位型別,我們會使用match query的查詢方式;而json是一種key-value的儲存格式,有key在前,value在後的特點,text欄位型別就使用match phrase query的方式。

如下我們的業務資料做測試,在我們的測試場景下,部分匹配查詢耗時較長,設定為整詞匹配模式效能能提公升10倍之上。

文件數查詢方式 7億 7000萬 1000萬

wildcard 25s 4.7s 1.6s

match 2.3s 400ms 130ms

match phrase 2.5s 500ms 180ms

es 父子查詢 es父子文件建立查詢

一 準備 1,elasticsearch 5.6.9 2,kibana 5.6.9 3,jdk1.8 二 建立索引,文件 1建立資料庫put database?pretty station stationname 三 填充資料 插入父文件一條記錄 插入id 1的6路post database lin...

ES查詢語句

1.萬用字元查詢keyword欄位 不會建分詞索引,會建索引 2.刪除並釋放磁碟空間 post monitor delete by query 1.查詢你要刪除的doc資料 以2019 5 18 00 00 00時間節點和time欄位為例 具體 如下 monitor search post 2.手動...

ES 常用查詢

1.term精確查詢,實際上是包含的意思 用法一 與bool,filter使用 get zf en search 用法二 直接term查詢 get zf en search 2.bulk 批量寫入,注意,必須指定 id,須換行 如果 id存在,執行的是update操作 3.組合查詢,bool 布林 ...