es查询所欲_Elasticsearch基本查询总结
Elasticsearch是一個(gè)分布式文檔存儲(chǔ)。Elasticsearch不會(huì)將信息存儲(chǔ)為列數(shù)據(jù)的行,而是存儲(chǔ)已序列化為JSON文檔的復(fù)雜數(shù)據(jù)結(jié)構(gòu)。當(dāng)集群中有多個(gè)Elasticsearch節(jié)點(diǎn)時(shí),存儲(chǔ)的文檔將分布在集群中,并且可以從任何節(jié)點(diǎn)立即訪問(wèn)。
存儲(chǔ)文檔時(shí),將在1秒鐘內(nèi)幾乎實(shí)時(shí)地對(duì)其進(jìn)行索引和完全搜索。Elasticsearch使用稱為倒排索引的數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)支持非常快速的全文本搜索。反向索引列出了出現(xiàn)在任何文檔中的每個(gè)唯一單詞,并標(biāo)識(shí)了每個(gè)單詞出現(xiàn)的所有文檔。
索引可以認(rèn)為是文檔的優(yōu)化集合,每個(gè)文檔都是字段的集合,這些字段是包含數(shù)據(jù)的鍵值對(duì)。默認(rèn)情況下,Elasticsearch對(duì)每個(gè)字段中的所有數(shù)據(jù)建立索引,并且每個(gè)索引字段都具有專用的優(yōu)化數(shù)據(jù)結(jié)構(gòu)。例如,文本字段存儲(chǔ)在倒排索引中,數(shù)字字段和地理字段存儲(chǔ)在BKD樹(shù)中。使用按字段數(shù)據(jù)結(jié)構(gòu)組合并返回搜索結(jié)果的能力使Elasticsearch如此之快。
Elasticsearch還具有無(wú)模式的能力,這意味著無(wú)需顯式指定如何處理文檔中可能出現(xiàn)的每個(gè)不同字段即可對(duì)文檔建立索引。啟用動(dòng)態(tài)映射后,Elasticsearch自動(dòng)檢測(cè)并向索引添加新字段。此默認(rèn)行為使索引和瀏覽數(shù)據(jù)變得容易-只需開(kāi)始建立索引文檔,Elasticsearch就會(huì)檢測(cè)布爾值,浮點(diǎn)數(shù)和整數(shù)值,日期和字符串并將其映射到適當(dāng)?shù)腅lasticsearch數(shù)據(jù)類型。
1.ES與常用數(shù)據(jù)庫(kù)比較
2.?查詢操作
Elasticsearch中當(dāng)我們?cè)O(shè)置Mapping(分詞器、字段類型)完畢后,就可以按照設(shè)定的方式導(dǎo)入數(shù)據(jù)。
有了數(shù)據(jù)后,我們就需要對(duì)數(shù)據(jù)進(jìn)行檢索操作。根據(jù)實(shí)際開(kāi)發(fā)需要,往往我們需要支持包含但不限于以下類型的檢索:
1)精確匹配,類似mysql中的 “=”操作;
2)模糊匹配,類似mysql中的”like %關(guān)鍵詞% “查詢操作;
3)前綴匹配;
4)通配符匹配;
5)正則表達(dá)式匹配;
6)跨索引匹配;
7)提升精讀匹配。
細(xì)數(shù)一下,我們的痛點(diǎn)在于:
1)ES究竟支持哪些檢索操作?
2)如何實(shí)現(xiàn)ES精確值檢索、指定索引檢索、全文檢索?
這些就是本文著重參考ES最新官方文檔,針對(duì)ES5.X版本探討的內(nèi)容。
0、檢索概覽
檢索子句的行為取決于查詢應(yīng)用于過(guò)濾(filter)上下文還是查詢/分析(query)上下文。
過(guò)濾上下文——對(duì)應(yīng)于結(jié)構(gòu)化檢索
1)核心回答的問(wèn)題是:“這個(gè)文檔是否符合這個(gè)查詢條款?”2)答案是簡(jiǎn)單的是或否,不計(jì)算分?jǐn)?shù)。3)過(guò)濾器上下文主要用于過(guò)濾結(jié)構(gòu)化數(shù)據(jù)。類似于Mysql中判定某個(gè)字段是否存在:
例如:
a. 時(shí)間戳字段:是否屬于2015年或2016年?
b. 狀態(tài)字段:是否設(shè)置為“已發(fā)布”?
經(jīng)常使用的過(guò)濾器將被Elasticsearch**自動(dòng)緩存,以加快性能**。
分析上下文——對(duì)應(yīng)于全文檢索
1)核心回答了“本文檔與此查詢子句是否匹配?”的問(wèn)題。
2)除了決定文檔是否匹配之外,查詢子句還會(huì)計(jì)算一個(gè)_score,表示文檔與其他文檔的匹配程度。
綜合應(yīng)用場(chǎng)景如下:
GET /_search
{"query": { "bool": { "must": [
{"match": { "title": "Search"}},
{"match": { "content": "Elasticsearch"}}
],"filter": [
{"term": { "status": "published"}},
{"range": { "publish_date": { "gte": "2015-01-01"}}}
]
}
}
以上檢索,title中包含”Search”并且content中包含 “Elasticsearch”,status中精確匹配”published”,并且publish_date 大于“2015-01-01”的全部信息。
以下,以“腦圖”的形式直觀展示檢索分類。
其中,3-7根據(jù)我隨著我開(kāi)發(fā)深入再做更新。
以下內(nèi)容的原文需要參考ES官方文檔(隨著版本變化,后續(xù)會(huì)有更新)
1、結(jié)構(gòu)化檢索
針對(duì)字段類型: 日期、時(shí)間、數(shù)字類型,以及精確的文本匹配。
結(jié)構(gòu)化檢索特點(diǎn):
* 1)結(jié)構(gòu)化查詢,我們得到的結(jié)果 總是 非是即否,要么存于集合之中,要么存在集合之外。
* 2)結(jié)構(gòu)化查詢不關(guān)心文件的相關(guān)度或評(píng)分;它簡(jiǎn)單的對(duì)文檔包括或排除處理。
1.1 精確值查找
1.1.1 單個(gè)精確值查找(term query)
term 查詢會(huì)查找我們指定的精確值。term 查詢是簡(jiǎn)單的,它接受一個(gè)字段名以及我們希望查找的數(shù)值。
想要類似mysql中如下sql語(yǔ)句的查詢操作:
SELECT document FROM products WHERE price = 20;
DSL寫法:
GET /my_store/products/_search
{"query": {"term": {"price" : 20}
}
當(dāng)進(jìn)行精確值查找時(shí), 我們會(huì)使用過(guò)濾器(filters)。過(guò)濾器很重要,因?yàn)樗鼈儓?zhí)行速度非常快,不會(huì)計(jì)算相關(guān)度(直接跳過(guò)了整個(gè)評(píng)分階段)而且很容易被緩存。如下: 使用 constant_score 查詢以非評(píng)分模式來(lái)執(zhí)行 term 查詢并以一作為統(tǒng)一評(píng)分。
GET /my_store/products/_search
{"query": {"constant_score": {"filter": {"term": {"price" : 20}
}
}
}
注意:5.xES中,對(duì)于字符串類型,要進(jìn)行精確值匹配。需要講類型設(shè)置為text和keyword兩種類型。mapping設(shè)置如下:
POST testindex/testtype/_mapping
{"testtype":{"properties":{"title":{"type":"text","analyzer":"ik_max_word","search_analyzer":"ik_max_word","fields":{"keyword":{"type":"keyword"}
}
}
}
精確值java api jest使用方法:
searchSourceBuilder.query(QueryBuilders.termQuery(“text.keyword”, “來(lái)自新華社的報(bào)道”));
1.1.2 布爾過(guò)濾器
一個(gè) bool 過(guò)濾器由三部分組成:
{"bool": {"must": [],"should": [],"must_not": [],"filter": []
}
}
must ——所有的語(yǔ)句都 必須(must) 匹配,與 AND 等價(jià)。
must_not ——所有的語(yǔ)句都 不能(must not) 匹配,與 NOT 等價(jià)。
should ——至少有一個(gè)語(yǔ)句要匹配,與 OR 等價(jià)。
filter——必須匹配,運(yùn)行在非評(píng)分&過(guò)濾模式。
就這么簡(jiǎn)單! 當(dāng)我們需要多個(gè)過(guò)濾器時(shí),只須將它們置入 bool 過(guò)濾器的不同部分即可。
舉例:
GET /my_store/products/_search
{"query": {"filtered": {"filter": {"bool": {"should": [
{"term" : {"price" : 20}},
{"term" : {"productID" : "XHDK-A-1293-#fJ3"}}
],"must_not": {"term" : {"price" : 30}
}
}
}
}
}
1.1.3 多個(gè)值精確查找(terms query)
{"terms": {"price" : [20, 30]
}
}
如上,terms是包含的意思,包含20或者包含30。
如下實(shí)現(xiàn)嚴(yán)格意義的精確值檢索, tag_count代表必須匹配的次數(shù)為1。
GET /my_index/my_type/_search
{"query": {"constant_score": {"filter": {"bool": {"must": [
{"term" : { "tags" : "search"} },
{"term" : { "tag_count" : 1} }
]
}
}
}
}
}
1.2 范圍檢索(range query)
range 查詢可同時(shí)提供包含(inclusive)和不包含(exclusive)這兩種范圍表達(dá)式,可供組合的選項(xiàng)如下:
gt: >大于(greater than)
lt:
gte:>= 大于或等于(greater than orequal to)
lte:<= 小于或等于(less than or equal to)
類似Mysql中的范圍查詢:
SELECTdocumentFROMproductsWHERE price BETWEEN 20 AND 40
ES中對(duì)應(yīng)的DSL如下:
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"range" : {
"price" : {
"gte" :20,
"lt" :40}
}
}
}
}
}
1.3 存在與否檢索(exist query)
mysql中,有如下sql:
SELECT tags FROM posts WHERE tags IS NOT NULL;
ES中,exist查詢某個(gè)字段是否存在:
GET /my_index/posts/_search
{
"query" : {
"constant_score" : {
"filter" : {
"exists" : { "field" : "tags" }
}
}
}
}
若想要exist查詢能匹配null類型,需要設(shè)置mapping:
"user": {
"type": "keyword",
"null_value": "_null_"
}
missing查詢?cè)?.x版本已經(jīng)不存在,改成如下的判定形式:
GET /_search
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "user"
}
}
}
}
}
1.4 前綴檢索( Prefix Query )
匹配包含 not analyzed 的前綴字符:
GET /_search
{ "query": {
"prefix" : { "user" : "ki" }
}
}
1.5 通配符檢索( wildcard query)
匹配具有匹配通配符表達(dá)式( (not analyzed )的字段的文檔。 支持的通配符:
1)*,它匹配任何字符序列(包括空字符序列);
2)?,它匹配任何單個(gè)字符。
請(qǐng)注意,此查詢可能很慢,因?yàn)樗枰闅v多個(gè)術(shù)語(yǔ)。
為了防止非常慢的通配符查詢,通配符不能以任何一個(gè)通配符*或?開(kāi)頭。
舉例:
GET /_search
{
"query": {
"wildcard" : { "user" : "ki*y" }
}
}
1.6 正則表達(dá)式檢索(regexp query)
正則表達(dá)式查詢?cè)试S您使用正則表達(dá)式術(shù)語(yǔ)查詢。
舉例如下:
GET /_search
{
"query": {
"regexp":{
"name.first": "s.*y"
}
}
}
注意: *的匹配會(huì)非常慢,你需要使用一個(gè)長(zhǎng)的前綴,
通常類似.*?+通配符查詢的正則檢索性能會(huì)非常低。
1.7 模糊檢索(fuzzy query)
模糊查詢查找在模糊度中指定的最大編輯距離內(nèi)的所有可能的匹配項(xiàng),然后檢查術(shù)語(yǔ)字典,以找出在索引中實(shí)際存在待檢索的關(guān)鍵詞。
舉例如下:
GET /_search
{
"query": {
"fuzzy" : { "user" : "ki" }
}
}
1.8 類型檢索(type query)
舉例:
GET /my_index/_search
{
"query": {
"type" : {
"value" : "xext"
}
}
}
已驗(yàn)證,檢索索引my_index中,type為xext的全部信息。
1.9 Ids檢索(ids query)
返回指定id的全部信息。
GET /my_index/_search
{
"query": {
"ids" : {
"type" : "xext",
"values" : ["2", "4", "100"]}
}
}
2、全文檢索
高級(jí)全文查詢通常用于在全文本字段(如電子郵件正文)上運(yùn)行全文查詢。他們了解如何對(duì)被查詢的字段進(jìn)行分析,并在執(zhí)行前將每個(gè)字段的分析器(或search_analyzer)應(yīng)用于查詢字符串。
2.1 匹配檢索(match query)
匹配查詢接受文本/數(shù)字/日期類型,分析它們,并構(gòu)造查詢。
1)匹配查詢的類型為boolean。 這意味著分析所提供的文本,并且分析過(guò)程從提供的文本構(gòu)造一個(gè)布爾查詢,
可以將運(yùn)算符標(biāo)志設(shè)置為或以控制布爾子句(默認(rèn)為或);
2)文本分析取決于mapping中設(shè)定的analyzer(中文分詞,我們默認(rèn)選擇ik分詞器);
3) fuzziness——模糊性允許基于被查詢的字段的類型進(jìn)行模糊匹配;
4)”operator”: “and”——匹配與操作(默認(rèn)或操作);
5) “minimum_should_match”: “75%”——這讓我們可以指定必須匹配的詞項(xiàng)數(shù)用來(lái)表示一個(gè)文檔是否相關(guān)。
舉例:
GET /_search
{
"query": {
"match" : {
"message" : {
"query" : "thisisa test",
"operator" : "and"
}
}
}
}
2.2 匹配解析檢索 match_phrase query
match_phrase查詢分析文本,并從分析文本中創(chuàng)建短語(yǔ)查詢。
類似 match 查詢, match_phrase 查詢首先將查詢字符串解析成一個(gè)詞項(xiàng)列表,然后對(duì)這些詞項(xiàng)進(jìn)行搜索,但只保留那些包含 全部 搜索詞項(xiàng),且 位置 與搜索詞項(xiàng)相同的文檔。
舉例如下:對(duì)于 quick fox 的短語(yǔ)搜索可能不會(huì)匹配到任何文檔,因?yàn)闆](méi)有文檔包含的 quick 詞之后緊跟著 fox 。
GET /my_index/my_type/_search
{
"query": {
"match_phrase": {
"title": "quick brown fox"
}
}
}
2.3 匹配解析前綴檢索(match_phrase_prefix)
用戶已經(jīng)漸漸習(xí)慣在輸完查詢內(nèi)容之前,就能為他們展現(xiàn)搜索結(jié)果,這就是所謂的 即時(shí)搜索(instant search) 或 輸入即搜索(search-as-you-type) 。
不僅用戶能在更短的時(shí)間內(nèi)得到搜索結(jié)果,我們也能引導(dǎo)用戶搜索索引中真實(shí)存在的結(jié)果。
例如,如果用戶輸入 johnnie walker bl ,我們希望在它們完成輸入搜索條件前就能得到:
Johnnie Walker Black Label 和 Johnnie Walker Blue Label 。
match_phrase_prefix與match_phrase相同,除了它允許文本中最后一個(gè)術(shù)語(yǔ)的前綴匹配。
舉例:
GET /_search
{
“query”:{
“match_phrase_prefix”:{
“message”:“quick brown f”
}
}
}
2.4 多字段匹配檢索( multi_match query)
multi_match 查詢?yōu)槟茉诙鄠€(gè)字段上反復(fù)執(zhí)行相同查詢提供了一種便捷方式。
默認(rèn)情況下,查詢的類型是 best_fields, 這表示它會(huì)為每個(gè)字段生成一個(gè) match 查詢。
舉例1:”fields”: “*_title”
——任何與模糊模式正則匹配的字段都會(huì)被包括在搜索條件中, 例如可以左側(cè)的方式同時(shí)匹配 book_title 、 chapter_title 和 section_title (書(shū)名、章名、節(jié)名)這三個(gè)字段。
舉例2: “fields”: [ “*_title”, “chapter_title^2” ]
——可以使用 ^ 字符語(yǔ)法為單個(gè)字段提升權(quán)重,在字段名稱的末尾添加 ^boost , 其中 boost 是一個(gè)浮點(diǎn)數(shù)。
舉例3:”fields”: [ “first_name”, “l(fā)ast_name” ],
“operator”: “and”
——兩個(gè)字段必須都包含。
GET /_search
{
"query": {
"multi_match" : {
"query": "thisisa test",
"fields":["subject", "message"]}
}
}
2.5 字符串檢索(query_string)
一個(gè)使用查詢解析器解析其內(nèi)容的查詢。
query_string查詢提供了以簡(jiǎn)明的簡(jiǎn)寫語(yǔ)法執(zhí)行多匹配查詢 multi_match queries ,布爾查詢 bool queries ,提升得分 boosting ,模糊匹配 fuzzy matching ,通配符 wildcards ,正則表達(dá)式 regexp 和范圍查詢 range queries 的方式。
支持參數(shù)達(dá)10幾種。
GET /_search
{
"query": {
"query_string" : {
"default_field" : "content",
"query" : "thisAND that ORthus"
}
}
}
2.6 簡(jiǎn)化字符串檢索(simple_query_string)
一個(gè)使用SimpleQueryParser解析其上下文的查詢。 與常規(guī)query_string查詢不同,simple_query_string查詢永遠(yuǎn)不會(huì)拋出異常,并丟棄查詢的無(wú)效部分。
舉例:
GET /_search
{
"query": {
"simple_query_string" : {
"fields" :["content"],
"query" : "foo bar-baz"
}
}
}
支持的操作如下:
1)+表示AND操作
2)| 表示OR操作
3)- 否定操作
4)*在術(shù)語(yǔ)結(jié)束時(shí)表示前綴查詢
5)(和)表示優(yōu)先
總結(jié)
以上是生活随笔為你收集整理的es查询所欲_Elasticsearch基本查询总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 485通讯线是几芯的_485总线,通讯线
- 下一篇: 转移到ios下载安卓_安卓和IOS角色互