国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn)

這篇具有很好參考價(jià)值的文章主要介紹了【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言

個(gè)人在學(xué)習(xí)的過(guò)程中,感覺(jué)比較吃力的地方有如下:

  1. 語(yǔ)法結(jié)構(gòu)比較陌生
  2. 沒(méi)有中文文檔, 只能看英文
  3. 其他博客也比較少介紹語(yǔ)法結(jié)構(gòu)。比如說(shuō),為什么查詢(xún)中會(huì)出現(xiàn)query關(guān)鍵詞

閱讀對(duì)象

有ES入門(mén)基礎(chǔ),且想進(jìn)一步學(xué)習(xí)ES基本操作的朋友

閱讀導(dǎo)航

系列上一篇文章:《【ES專(zhuān)題】ElasticSearch快速入門(mén)》
系列下一篇文章:《【ES專(zhuān)題】ElasticSearch搜索進(jìn)階》

官方文檔地址:ES官方使用文檔-英文

前置知識(shí)

  1. 理解ES的核心概念,最最重要的是【索引】和【文檔】
  2. 了解基本的索引、文檔操作
  3. 了解RESTFul風(fēng)格

數(shù)據(jù)準(zhǔn)備

為了方便后面的查詢(xún)演示,我們先在ES中創(chuàng)建/es_db索引,并創(chuàng)建一些文檔。

#指定ik分詞器
PUT /es_db
{
  "settings" : {
      "index" : {
          "analysis.analyzer.default.type": "ik_max_word"
      }
  }
}

# 創(chuàng)建文檔,指定id
PUT /es_db/_doc/1
{
"name": "張三",
"sex": 1,
"age": 25,
"address": "廣州天河公園",
"remark": "java developer"
}
PUT /es_db/_doc/2
{
"name": "李四",
"sex": 1,
"age": 28,
"address": "廣州荔灣大廈",
"remark": "java assistant"
}

PUT /es_db/_doc/3
{
"name": "王五",
"sex": 0,
"age": 26,
"address": "廣州白云山公園",
"remark": "php developer"
}

PUT /es_db/_doc/4
{
"name": "趙六",
"sex": 0,
"age": 22,
"address": "長(zhǎng)沙橘子洲",
"remark": "python assistant"
}

PUT /es_db/_doc/5
{
"name": "張龍",
"sex": 0,
"age": 19,
"address": "長(zhǎng)沙麓谷企業(yè)廣場(chǎng)",
"remark": "java architect assistant"
}    
    
PUT /es_db/_doc/6
{
"name": "趙虎",
"sex": 1,
"age": 32,
"address": "長(zhǎng)沙麓谷興工國(guó)際產(chǎn)業(yè)園",
"remark": "java architect"
}    

PUT /es_db/_doc/7
{
"name": "李虎",
"sex": 1,
"age": 32,
"address": "廣州番禺節(jié)能科技園",
"remark": "java architect"
}

PUT /es_db/_doc/8
{
"name": "張星",
"sex": 1,
"age": 32,
"address": "武漢東湖高新區(qū)未來(lái)智匯城",
"remark": "golang developer"
}

筆記正文

一、ES高級(jí)查詢(xún)Query DSL

1.1 基本介紹

就跟Mysql有自己的查詢(xún)語(yǔ)言一樣,ES作為一款優(yōu)秀的分布式文檔存儲(chǔ)和【搜索引擎】,它也有自己的查詢(xún)語(yǔ)言。即:Query DSL(查詢(xún)Domain Specific Language),查詢(xún)領(lǐng)域?qū)S谜Z(yǔ)言。Query DSL是利用RESTfull風(fēng)格API傳遞JSON格式的請(qǐng)求體(RequestBody)數(shù)據(jù)與ES進(jìn)行交互,這種方式的豐富查詢(xún)語(yǔ)法讓ES檢索變得更強(qiáng)大,更簡(jiǎn)潔。

上面高亮處是否有似曾像是的感覺(jué)?我第一眼覺(jué)得,這不跟做http請(qǐng)求差不多嘛。基于ES是Java寫(xiě)的,我嚴(yán)重懷疑…

Elasticsearch 提供了基于 JSON 的完整查詢(xún) DSL(查詢(xún)領(lǐng)域特定語(yǔ)言)來(lái)定義查詢(xún)。在ES的Query DSL中,大體可以分為兩類(lèi):葉查詢(xún)子句(我更喜歡叫:簡(jiǎn)單查詢(xún))以及復(fù)合查詢(xún)子句(復(fù)雜查詢(xún))。

總的來(lái)說(shuō),ES支持很多種查詢(xún)方式,所以,在后面的舉例中我不會(huì)全部都介紹一遍,而只是把我們工作中【據(jù)說(shuō)】可能比較常用的大概介紹一遍。(畢竟我自己也沒(méi)有生產(chǎn)使用經(jīng)驗(yàn))

在DSL中,所有的查詢(xún)都以下面這種范式開(kāi)頭:

比如下面的語(yǔ)法示例:

GET /index_name/_doc/_search 
{
	"query": {
		json請(qǐng)求體數(shù)據(jù)
	}
}

# 可以簡(jiǎn)寫(xiě)成下面的
GET /index_name/_search 
{
	"query": {
		json請(qǐng)求體數(shù)據(jù)
	}
}

# 查詢(xún)指定字段則是如下
GET /index_name/_search 
{
	"query": {
		"field_name": {
			json請(qǐng)求體數(shù)據(jù)
		}
	}
}

來(lái)個(gè)簡(jiǎn)單的使用示例:

#無(wú)條件查詢(xún),默認(rèn)返回10條數(shù)據(jù)
GET /es_db/_search
{
    "query":{
        "match_all":{}
    }
}

然后,再給個(gè)返回圖解給大家稍微看看字段是什么意思。
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java

1.2 簡(jiǎn)單查詢(xún)之——match-all(匹配所有)

語(yǔ)法格式如下:

GET /index_name/_search
{
    "query":{
        "match_all":{}
    }
}

值得注意的是,使用match_all,匹配所有文檔,默認(rèn)只會(huì)返回10條數(shù)據(jù)。因?yàn)?code>_search查詢(xún)默認(rèn)采用的是【分頁(yè)查詢(xún)】,每頁(yè)記錄數(shù)size的默認(rèn)值為10。如果想顯示更多數(shù)據(jù),指定size。
簡(jiǎn)單的使用示例如下:

GET /es_db/_search
等同于
GET /es_db/_search
{
    "query": {
        "match_all": {}
    }
}
1.2.1 返回源數(shù)據(jù)_source

_source關(guān)鍵字: 是一個(gè)數(shù)組,在數(shù)組中用來(lái)指定展示那些字段。語(yǔ)法格式我就不貼了,直接看時(shí)使用示例就行了,如下:

# 返回指定字段
GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "_source": ["name","address"]
}

#在查詢(xún)中過(guò)濾
#不查看源數(shù)據(jù),僅查看元字段
{
  "_source": false,
  "query": {
    ...
  } 
}

#只看以obj.開(kāi)頭的字段(其實(shí)這里就是通配符)
{
  "_source": "obj.*",
  "query": {
    ...
  } 
}
1.2.2 返回指定條數(shù)size

size關(guān)鍵字: 指定查詢(xún)結(jié)果中返回指定條數(shù)。 默認(rèn)返回值10條

學(xué)到這里的時(shí)候我有點(diǎn)懵,為啥這里不以下劃線開(kāi)頭_size,?。。?!太沒(méi)規(guī)范了吧

GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "size": 100
}
1.2.3 分頁(yè)查詢(xún)from&size

size:顯示應(yīng)該返回的結(jié)果數(shù)量,默認(rèn)是 10
from:顯示應(yīng)該跳過(guò)的初始結(jié)果數(shù)量,默認(rèn)是 0
from 關(guān)鍵字用來(lái)指定起始返回位置,和size關(guān)鍵字連用可實(shí)現(xiàn)分頁(yè)效果

跟Mysql中的limit很像,原理也是

GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 5  
}
1.2.4 指定字段排序sort

注意:會(huì)讓得分失效

GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": "desc"
    }
  ]
}

#排序,分頁(yè)
GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": "desc"
    }
  ],
  "from": 10,
  "size": 5
}

1.3 簡(jiǎn)單查詢(xún)之——Term-Level Queries(術(shù)語(yǔ)級(jí)別查詢(xún),精確匹配)

術(shù)語(yǔ)級(jí)別查詢(xún)(Term-Level Queries)指的是:搜索內(nèi)容不經(jīng)過(guò)文本分析直接用于文本匹配,這個(gè)過(guò)程類(lèi)似于數(shù)據(jù)庫(kù)的SQL查詢(xún),搜索的對(duì)象大多是索引的非text類(lèi)型字段。Elasticsearch 中的一些術(shù)語(yǔ)級(jí)別查詢(xún)示例包括 term、terms 和 range 查詢(xún)。

不經(jīng)過(guò)文本分析是指:不對(duì)查詢(xún)語(yǔ)句分詞了,輸入什么就拿什么去【索引文檔】中匹配

1.3.1 Term query術(shù)語(yǔ)查詢(xún)(詞項(xiàng)查詢(xún))

術(shù)語(yǔ)查詢(xún)直接返回包含搜索內(nèi)容的文檔,常用來(lái)查詢(xún)索引中某個(gè)類(lèi)型為keyword的文本字段,類(lèi)似于SQL的【=】查詢(xún),使用十分普遍。

注意:最好不要對(duì)text字段使用term查詢(xún),因?yàn)閠ext字段會(huì)被分詞,這樣做既沒(méi)有意義,還很有可能什么也查不到。
另外,term大家不知道還熟悉否?這不就是ES概念中的【詞項(xiàng)】嘛,所以我更喜歡稱(chēng)呼Term Query為【詞項(xiàng)查詢(xún)】。理論上來(lái)說(shuō),ES所有文檔的source皆為詞項(xiàng),只不過(guò)有一種比較特殊的情況是:text類(lèi)型的字段會(huì)先被分詞成多個(gè)【詞項(xiàng)】寫(xiě)入倒排索引中。所以,對(duì)text類(lèi)型的字段做【詞項(xiàng)查詢(xún)】的時(shí)候要注意【分詞】的情況了。(查詢(xún)字符串不分詞,但是文檔記錄在被寫(xiě)入的時(shí)候已經(jīng)被分詞了)

接下來(lái)我們來(lái)三個(gè)查詢(xún)給大家演示一下,詞項(xiàng)查詢(xún)的效果。

查詢(xún)一:精確匹配,查找age為28的記錄

# 對(duì)bool,日期,數(shù)字,結(jié)構(gòu)化的文本可以利用term做精確匹配
# term 精確匹配
GET /es_db/_search
{
  "query": {
    "term": {
      "age": {
        "value": 28
      }
    }
  }
}

根據(jù)我們前面的演示數(shù)據(jù),age=28的數(shù)據(jù)即:李四。查詢(xún)結(jié)果如下:
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
查詢(xún)二:對(duì)text字段查詢(xún)

GET /es_db/_search
{
  "query":{
    "term": {
      "address": {
        "value": "廣州白云"
      }
    }
  }
}

大家思考下,上面的查詢(xún)有數(shù)據(jù)嘛?畢竟我們?cè)跍?zhǔn)備數(shù)據(jù)中id==3王五地址就是廣州白云山公園
哈,答案是沒(méi)有的。因?yàn)槲覀兊?code>es_db索引使用的分詞器為ik_max_word,最細(xì)粒度的拆分。我們來(lái)看看這個(gè)分詞器下的拆分結(jié)果:
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
看,沒(méi)有我們查詢(xún)的廣州白云詞項(xiàng),所以查找無(wú)數(shù)據(jù)返回。

查詢(xún)?nèi)和ㄟ^(guò)keyword對(duì)text字段精確查詢(xún)

# 采用term精確查詢(xún), 查詢(xún)字段映射類(lèi)型為keyword
GET /es_db/_search
{
  "query":{
    "term": {
      "address.keyword": {
        "value": "廣州白云山公園"
      }
    }
  }
}

結(jié)果如下:
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java

在ES中,Term查詢(xún),對(duì)輸入不做分詞。會(huì)將輸入作為一個(gè)整體,在倒排索引中查找準(zhǔn)確的詞項(xiàng),并且使用相關(guān)度算分公式為每個(gè)包含該詞項(xiàng)的文檔進(jìn)行相關(guān)度算分。
可以通過(guò)Constant Score操作將查詢(xún)轉(zhuǎn)換成一個(gè)Filtering,避免算分,并利用緩存,提高性能。

  • 將Query 轉(zhuǎn)成 Filter,忽略TF-IDF計(jì)算,避免相關(guān)性算分的開(kāi)銷(xiāo)
  • Filter可以有效利用緩存
GET /es_db/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "address.keyword": "廣州白云山公園"
        }
      }
    }
  }
}

term處理多值字段時(shí)(數(shù)組),term查詢(xún)是包含,不是等于。

POST /employee/_bulk
{"index":{"_id":1}}
{"name":"小明","interest":["跑步","籃球"]}
{"index":{"_id":2}}
{"name":"小紅","interest":["跳舞","畫(huà)畫(huà)"]}
{"index":{"_id":3}}
{"name":"小麗","interest":["跳舞","唱歌","跑步"]}

POST /employee/_search
{
  "query": {
    "term": {
      "interest.keyword": {
        "value": "跑步"
      }
    }
  }
}
1.3.2 Terms Query多術(shù)語(yǔ)查詢(xún)

Terms query用于在指定字段上匹配多個(gè)詞項(xiàng)(terms)。它會(huì)精確匹配指定字段中包含的任何一個(gè)詞項(xiàng)。

POST /es_db/_search
{
  "query": {
    "terms": {
      "remark.keyword": ["java assistant", "java architect"]
    }
  }
}

1.3.3 exists query是否存在字段查詢(xún)

在Elasticsearch中可以使用exists進(jìn)行查詢(xún),以判斷文檔中是否存在對(duì)應(yīng)的字段。
注意:這里是判斷【字段】是否存在,而不是文檔數(shù)據(jù)

#查詢(xún)索引庫(kù)中存在remarks字段的文檔數(shù)據(jù)
GET /es_db/_search
{
  "query": {
    "exists": 
    {
      "field": "remark"
    }
  }
}
1.3.4 ids query——id數(shù)組查詢(xún)

ids關(guān)鍵字 : 值為數(shù)組類(lèi)型,用來(lái)根據(jù)一組id獲取多個(gè)對(duì)應(yīng)的文檔

GET /es_db/_search
{
  "query": {
    "ids": {
      "values": [1,2]
    }
  }
}
1.3.5 range query范圍查詢(xún)

range:范圍關(guān)鍵字。它的取值如下:

  • gte 大于等于
  • lte 小于等于
  • gt 大于
  • lt 小于
  • now 當(dāng)前時(shí)間
POST /es_db/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 25,
        "lte": 28
      }
    }
  }
}

#日期范圍比較
DELETE /product
POST /product/_bulk
{"index":{"_id":1}}
{"price":100,"date":"2021-01-01","productId":"XHDK-1293"}
{"index":{"_id":2}}
{"price":200,"date":"2022-01-01","productId":"KDKE-5421"}

GET /product/_mapping

GET /product/_search
{
  "query": {
    "range": {
      "date": {
        "gte": "now-2y"
      }
    }
  }
}
1.3.6 prefix query前綴查詢(xún)

它會(huì)對(duì)分詞后的文檔數(shù)據(jù)term進(jìn)行前綴搜索。

  • 它不會(huì)分析要搜索的字符串,傳入的前綴就是想要查找的前綴
  • 默認(rèn)狀態(tài)下,前綴查詢(xún)不做相關(guān)度分?jǐn)?shù)計(jì)算,它只是將所有匹配的文檔返回,然后賦予所有相關(guān)分?jǐn)?shù)值為1。它的行為更像是一個(gè)過(guò)濾器而不是查詢(xún)。兩者實(shí)際的區(qū)別就是過(guò)濾器是可以被緩存的,而前綴查詢(xún)不行

prefix的原理:需要遍歷所有倒排索引,并比較每個(gè)term是否以所指定的前綴開(kāi)頭

GET /es_db/_search
{
  "query": {
    "prefix": {
      "address": {
        "value": "廣州"
      }
    }
  }
}
1.3.7 wildcard query通配符查詢(xún)

通配符查詢(xún):工作原理和prefix相同,只不過(guò)它不是只比較開(kāi)頭,它能支持更為復(fù)雜的匹配模式。

通配符,大家都不陌生

GET /es_db/_search
{
  "query": {
    "wildcard": {
      "address": {
        "value": "*白*"
      }
    }
  }
}
1.3.8 fuzzy query模糊查詢(xún)

在實(shí)際的搜索中,我們有時(shí)候會(huì)打錯(cuò)字,從而導(dǎo)致搜索不到。在Elasticsearch中,我們可以使用fuzziness屬性來(lái)進(jìn)行模糊查詢(xún),從而達(dá)到搜索有錯(cuò)別字的情形。
fuzzy 查詢(xún)會(huì)用到兩個(gè)很重要的參數(shù),fuzziness,prefix_length

  • fuzziness:表示輸入的關(guān)鍵字通過(guò)幾次操作可以轉(zhuǎn)變成為ES庫(kù)里面的對(duì)應(yīng)field的字段
    • 操作是指:新增一個(gè)字符,刪除一個(gè)字符,修改一個(gè)字符,每次操作可以記做編輯距離為1;
    • 如【中文集團(tuán)】到【中威集團(tuán)】編輯距離就是1,只需要修改一個(gè)字符;如果fuzziness值在這里設(shè)置成2,會(huì)把編輯距離為2的【東東集團(tuán)】也查出來(lái)(所謂距離,可以理解為,允許錯(cuò)誤的字?jǐn)?shù)
    • 該參數(shù)默認(rèn)值為0,即不開(kāi)啟模糊查詢(xún); fuzzy 模糊查詢(xún) 最大模糊錯(cuò)誤必須在0-2之間
  • prefix_length:表示限制輸入關(guān)鍵字和ES對(duì)應(yīng)查詢(xún)field的內(nèi)容開(kāi)頭的前n個(gè)字符必須完全匹配,不允許錯(cuò)別字匹配;
    • 如這里等于1,則表示開(kāi)頭的字必須匹配,不匹配則不返回;
    • 默認(rèn)值也是0;
    • 加大prefix_length的值可以提高效率和準(zhǔn)確率。
GET /es_db/_search
{
  "query": {
    "fuzzy": {
      "address": {
        "value": "白運(yùn)山",
        "fuzziness": 1    
      }
    }
  }
}

1.4 簡(jiǎn)單查詢(xún)之——Full Text Queries(全文檢索)

全文檢索查詢(xún)(Full Text Queries)和術(shù)語(yǔ)級(jí)別查詢(xún)(Term-Level Queries)是 Elasticsearch 中搜索和檢索數(shù)據(jù)的兩種不同方法。
全文檢索查詢(xún)旨在基于相關(guān)性搜索和匹配文本數(shù)據(jù)這些查詢(xún)會(huì)對(duì)輸入的文本進(jìn)行分析,將其拆分為詞項(xiàng)(單個(gè)單詞),并執(zhí)行諸如分詞、詞干處理和標(biāo)準(zhǔn)化等操作。lasticsearch 中的一些全文檢索查詢(xún)示例包括match、match_phrase 和 multi_match 查詢(xún)。

全文檢索的關(guān)鍵特點(diǎn):

  • 對(duì)輸入的文本進(jìn)行分析,并根據(jù)分析后的詞項(xiàng)進(jìn)行搜索和匹配。全文檢索查詢(xún)會(huì)對(duì)輸入的文本進(jìn)行分析,將其拆分為詞項(xiàng),并基于這些詞項(xiàng)進(jìn)行搜索和匹配操作
  • 以相關(guān)性為基礎(chǔ)進(jìn)行搜索和匹配。全文檢索查詢(xún)使用相關(guān)性算法來(lái)確定文檔與查詢(xún)的匹配程度,并按照相關(guān)性進(jìn)行排序。相關(guān)性可以基于詞項(xiàng)的頻率、權(quán)重和其他因素來(lái)計(jì)算
  • 全文檢索查詢(xún)適用于包含自由文本數(shù)據(jù)的字段(text類(lèi)型),例如文檔的內(nèi)容、文章的正文或產(chǎn)品描述等

對(duì)于match查詢(xún),其底層邏輯的概述:

  1. 分詞:首先,輸入的查詢(xún)文本會(huì)被分詞器進(jìn)行分詞。分詞器會(huì)將文本拆分成一個(gè)個(gè)詞項(xiàng)(terms),如單詞、短語(yǔ)或特定字符。分詞器通常根據(jù)特定的語(yǔ)言規(guī)則和配置進(jìn)行操作。
  2. 倒排索引:ES使用倒排索引來(lái)加速搜索過(guò)程。倒排索引是一種數(shù)據(jù)結(jié)構(gòu),它將詞項(xiàng)映射到包含這些詞項(xiàng)的文檔。每個(gè)詞項(xiàng)都有一個(gè)對(duì)應(yīng)的倒排列表,其中包含了包含該詞項(xiàng)的所有文檔的引用。
  3. 匹配計(jì)算:一旦查詢(xún)被分詞,ES將根據(jù)查詢(xún)的類(lèi)型和參數(shù)計(jì)算文檔與查詢(xún)的匹配度。對(duì)于match查詢(xún),ES將比較查詢(xún)的詞項(xiàng)與倒排索引中的詞項(xiàng),并計(jì)算文檔的相關(guān)性得分。相關(guān)性得分衡量了文檔與查詢(xún)的匹配程度。
  4. 結(jié)果返回:根據(jù)相關(guān)性得分,ES將返回最匹配的文檔作為搜索結(jié)果。搜索結(jié)果通常按照相關(guān)性得分進(jìn)行排序,以便最相關(guān)的文檔排在前面。
1.4.1 match query匹配查詢(xún)

match在匹配時(shí)會(huì)對(duì)所查找的關(guān)鍵詞進(jìn)行分詞,然后按分詞匹配查找。
match支持以下參數(shù):

  • query : 指定匹配的值
  • operator : 匹配條件類(lèi)型
    • and : 條件分詞后都要匹配
    • or : 條件分詞后有一個(gè)匹配即可(默認(rèn)or
  • minmum_should_match : 最低匹配度,即條件在倒排索引中最低的匹配度
#match 分詞后or的效果
GET /es_db/_search
{
  "query": {
    "match": {
      "address": "廣州白云山公園"
    }
  }
}

# 分詞后 and的效果
GET /es_db/_search
{
  "query": {
    "match": {
      "address": {
        "query": "廣州白云山公園",
        "operator": "and"
      }
    }
  }
}

minnum_should_matchmatch中的應(yīng)用: 當(dāng)operator參數(shù)設(shè)置為or時(shí),minnum_should_match參數(shù)用來(lái)控制匹配的分詞的最少數(shù)量。

# 最少匹配廣州,公園兩個(gè)詞
GET /es_db/_search
{
  "query": {
    "match": {
      "address": {
        "query": "廣州公園",
        "minimum_should_match": 2
      }
    }
  }
}
1.4.2 multi_match query 多字段查詢(xún)

可以根據(jù)字段類(lèi)型,決定是否使用分詞查詢(xún),得分最高的在前面

GET /es_db/_search
{
  "query": {
    "multi_match": {
      "query": "長(zhǎng)沙張龍",
      "fields": [
        "address",
        "name"
      ]
    }
  }
}

注意:若字段類(lèi)型分詞,將查詢(xún)條件分詞之后進(jìn)行查詢(xún),如果該字段不分詞就會(huì)將查詢(xún)條件作為整體進(jìn)行查詢(xún)。

1.4.3 match_phrase query短語(yǔ)查詢(xún)

短語(yǔ)搜索(match phrase)會(huì)對(duì)搜索文本進(jìn)行文本分析,然后到索引中尋找搜索的每個(gè)分詞并要求分詞相鄰,你可以通過(guò)調(diào)整slop參數(shù)設(shè)置分詞出現(xiàn)的【最大間隔距離】。match_phrase會(huì)將檢索關(guān)鍵詞分詞。

下面兩個(gè)查詢(xún)將表現(xiàn)出不一樣的結(jié)果,這是i因?yàn)椤鞠噜彙績(jī)蓚€(gè)字在作怪

# 下面分詞之后得到:廣州、白云山、白云、云山
GET /es_db/_search
{
  "query": {
    "match_phrase": {
      "address": "廣州白云山"
    }
  }
}

# 下面分詞之后得到:廣州、白云、云山
GET /es_db/_search
{
  "query": {
    "match_phrase": {
      "address": "廣州白云"
    }
  }
}

思考:為什么查詢(xún)廣州白云山有數(shù)據(jù),廣州白云沒(méi)有數(shù)據(jù)?
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
分析原因:
【廣州白云山】分詞之后得到:廣州、白云山、白云、云山;
【廣州白云】分詞之后得到:廣州、白云、云山
match_phrase匹配的是相鄰的詞條,所以查詢(xún)廣州白云山有結(jié)果,但查詢(xún)廣州白云沒(méi)有結(jié)果。
如何解決詞條間隔的問(wèn)題?可以借助slop參數(shù),slop參數(shù)告訴match_phrase查詢(xún)?cè)~條能夠相隔多遠(yuǎn)時(shí)仍然將文檔視為匹配。

#廣州云山分詞后相隔為2,可以匹配到結(jié)果
GET /es_db/_search
{
  "query": {
    "match_phrase": {
      "address": {
        "query": "廣州云山",
        "slop": 2
      } 
    }
  }
}

1.4.4 query_string query

允許我們?cè)趩蝹€(gè)查詢(xún)字符串中指定AND | OR | NOT條件,同時(shí)也和 multi_match query 一樣,支持多字段搜索。和match類(lèi)似,但是match需要指定字段名,query_string是在所有字段中搜索,范圍更廣泛。

注意: 查詢(xún)字段分詞就將查詢(xún)條件分詞查詢(xún),查詢(xún)字段不分詞將查詢(xún)條件不分詞查詢(xún)

  • 未指定字段查詢(xún)
# AND 要求大寫(xiě)
GET /es_db/_search
{
  "query": {
    "query_string": {
      "query": "趙六 AND 橘子洲"
    }
  }
}
  • 指定單個(gè)字段查詢(xún)
#Query String
GET /es_db/_search
{
  "query": {
    "query_string": {
      "default_field": "address",
      "query": "白云山 OR 橘子洲"
    }
  }
}
  • 指定多個(gè)字段查詢(xún)
GET /es_db/_search
{
  "query": {
    "query_string": {
      "fields": ["name","address"],
      "query": "張三 OR (廣州 AND 王五)"
    }
  }
}
1.4.6 simple_query_string

類(lèi)似Query String,但是會(huì)忽略錯(cuò)誤的語(yǔ)法,同時(shí)只支持部分查詢(xún)語(yǔ)法,不支持AND OR NOT,會(huì)當(dāng)作字符串處理。支持部分邏輯:

  • +替代AND
  • |替代OR
  • -替代NOT
#simple_query_string 默認(rèn)的operator是OR
GET /es_db/_search
{
  "query": {
    "simple_query_string": {
      "fields": ["name","address"],
      "query": "廣州公園",
      "default_operator": "AND"
    }
  }
}

GET /es_db/_search
{
  "query": {
    "simple_query_string": {
      "fields": ["name","address"],
      "query": "廣州 + 公園"
    }
  }
}

1.5 復(fù)雜查詢(xún)之——bool query(布爾查詢(xún))

ES的復(fù)雜查詢(xún)其實(shí)有很多種,但這里只介紹這個(gè)了。感興趣的同學(xué)自己看文檔吧(嗚嗚嗚,那個(gè)文檔全英文的太難看懂了)

布爾查詢(xún)可以按照布爾邏輯條件組織多條查詢(xún)語(yǔ)句,只有符合整個(gè)布爾條件的文檔才會(huì)被搜索出來(lái)。在布爾條件中,可以包含兩種不同的上下文。

  1. 搜索上下文(query context):使用搜索上下文時(shí),Elasticsearch需要計(jì)算每個(gè)文檔與搜索條件的相關(guān)度得分,這個(gè)得分的計(jì)算需使用一套復(fù)雜的計(jì)算公式,有一定的性能開(kāi)銷(xiāo),帶文本分析的全文檢索的查詢(xún)語(yǔ)句很適合放在搜索上下文中
  2. 過(guò)濾上下文(filter context):使用過(guò)濾上下文時(shí),Elasticsearch只需要判斷搜索條件跟文檔數(shù)據(jù)是否匹配,例如使用Term query判斷一個(gè)值是否跟搜索內(nèi)容一致,使用Range query判斷某數(shù)據(jù)是否位于某個(gè)區(qū)間等。過(guò)濾上下文的查詢(xún)不需要進(jìn)行相關(guān)度得分計(jì)算,還可以使用緩存加快響應(yīng)速度,很多術(shù)語(yǔ)級(jí)查詢(xún)語(yǔ)句都適合放在過(guò)濾上下文中

布爾查詢(xún)一共支持4種組合類(lèi)型:
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java

PUT /books
{
  "settings": {
    "number_of_replicas": 1,
    "number_of_shards": 1
  },
  "mappings": {
    "properties": {
      "id": {
        "type": "long"
      },
      "title": {
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "language": {
        "type": "keyword"
      },
      "author": {
        "type": "keyword"
      },
      "price": {
        "type": "double"
      },
      "publish_time": {
        "type": "date",
        "format": "yyy-MM-dd"
      },
      "description": {
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

POST /_bulk
{"index":{"_index":"books","_id":"1"}}
{"id":"1", "title":"Java編程思想", "language":"java", "author":"Bruce Eckel", "price":70.20, "publish_time":"2007-10-01", "description":"Java學(xué)習(xí)必讀經(jīng)典,殿堂級(jí)著作!贏得了全球程序員的廣泛贊譽(yù)。"}
{"index":{"_index":"books","_id":"2"}}
{"id":"2","title":"Java程序性能優(yōu)化","language":"java","author":"葛一鳴","price":46.5,"publish_time":"2012-08-01","description":"讓你的Java程序更快、更穩(wěn)定。深入剖析軟件設(shè)計(jì)層面、代碼層面、JVM虛擬機(jī)層面的優(yōu)化方法"}
{"index":{"_index":"books","_id":"3"}}
{"id":"3","title":"Python科學(xué)計(jì)算","language":"python","author":"張若愚","price":81.4,"publish_time":"2016-05-01","description":"零基礎(chǔ)學(xué)python,光盤(pán)中作者獨(dú)家整合開(kāi)發(fā)winPython運(yùn)行環(huán)境,涵蓋了Python各個(gè)擴(kuò)展庫(kù)"}
{"index":{"_index":"books","_id":"4"}}
{"id":"4", "title":"Python基礎(chǔ)教程", "language":"python", "author":"Helant", "price":54.50, "publish_time":"2014-03-01", "description":"經(jīng)典的Python入門(mén)教程,層次鮮明,結(jié)構(gòu)嚴(yán)謹(jǐn),內(nèi)容翔實(shí)"}
{"index":{"_index":"books","_id":"5"}}
{"id":"5","title":"JavaScript高級(jí)程序設(shè)計(jì)","language":"javascript","author":"Nicholas C. Zakas","price":66.4,"publish_time":"2012-10-01","description":"JavaScript技術(shù)經(jīng)典名著"}


GET /books/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "java編程"
          }
        },{
          "match": {
            "description": "性能優(yōu)化"
          }
        }
      ]
    }
  }
}

GET /books/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "java編程"
          }
        },{
          "match": {
            "description": "性能優(yōu)化"
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}
GET /books/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "language": "java"
          }
        },
        {
          "range": {
            "publish_time": {
              "gte": "2010-08-01"
            }
          }
        }
      ]
    }
  }
}

1.6 highlight高亮

highlight關(guān)鍵字: 可以讓符合條件的文檔中的關(guān)鍵詞高亮。
highlight相關(guān)屬性:

  • pre_tags 前綴標(biāo)簽
  • post_tags 后綴標(biāo)簽
  • tags_schema 設(shè)置為styled可以使用內(nèi)置高亮樣式
  • require_field_match 多字段高亮需要設(shè)置為false

示例數(shù)據(jù):

#指定ik分詞器
PUT /products
{
  "settings" : {
      "index" : {
          "analysis.analyzer.default.type": "ik_max_word"
      }
  }
}

PUT /products/_doc/1
{
  "proId" : "2",
  "name" : "牛仔男外套",
  "desc" : "牛仔外套男裝春季衣服男春裝夾克修身休閑男生潮牌工裝潮流頭號(hào)青年春秋棒球服男 7705淺藍(lán)常規(guī) XL",
  "timestamp" : 1576313264451,
  "createTime" : "2019-12-13 12:56:56"
}

PUT /products/_doc/2
{
  "proId" : "6",
  "name" : "HLA海瀾之家牛仔褲男",
  "desc" : "HLA海瀾之家牛仔褲男2019時(shí)尚有型舒適HKNAD3E109A 牛仔藍(lán)(A9)175/82A(32)",
  "timestamp" : 1576314265571,
  "createTime" : "2019-12-18 15:56:56"
}

搜索測(cè)試:

GET /products/_search
{
  "query": {
    "term": {
      "name": {
        "value": "牛仔"
      }
    }
  },
  "highlight": {
    "fields": {
      "*":{}
    }
  }
}
1.6.1 自定義高亮html標(biāo)簽

可以在highlight中使用pre_tagspost_tags來(lái)自定義高亮html標(biāo)簽

GET /products/_search
{
  "query": {
    "multi_match": {
      "fields": ["name","desc"],
      "query": "牛仔"
    }
  },
  "highlight": {
    "post_tags": ["</span>"], 
    "pre_tags": ["<span style='color:red'>"],
    "fields": {
      "*":{}
    }
  }
}
1.6.2 多字段高亮
GET /products/_search
{
  "query": {
    "term": {
      "name": {
        "value": "牛仔"
      }
    }
  },
  "highlight": {
    "pre_tags": ["<font color='red'>"],
    "post_tags": ["<font/>"],
    "require_field_match": "false",
    "fields": {
      "name": {},
      "desc": {}
    }
  }
}

二、ES 深度分頁(yè)問(wèn)題及針對(duì)不同需求下的解決方案

說(shuō)到分頁(yè)問(wèn)題,這里有一個(gè)很有意思的東西想跟大家分享一下。
你們應(yīng)該記得分頁(yè)是怎么實(shí)現(xiàn)的吧?無(wú)非就這樣嘛:

select * from table_a where col=‘xxx’ limit 0, 100;
select * from table_a where col=‘xxx’ limit 101, 100;

但是不知道大家有沒(méi)有仔細(xì)研究過(guò),這條sql的性能問(wèn)題…
我直接說(shuō)吧:性能很差!因?yàn)?code>limit需要從表頭開(kāi)始遍歷數(shù)據(jù)。也就是對(duì)于第2條sql的limit 101,200來(lái)說(shuō),他仍然需要遍歷完前面的100條才開(kāi)始檢索第101-200條。也正是因?yàn)檫@個(gè)原因,其實(shí)非常推薦主鍵id不要用UUID的,而是使用自增的bigint。這樣就方便優(yōu)化,怎么優(yōu)化呢?【假設(shè)id是從0開(kāi)始自增】的情況下,上面的sql可以這么優(yōu)化:

select top 100 * from table_a where col=‘xxx’ and id > 0;
select top 100 * from table_a where col=‘xxx’ and id > 100;

因?yàn)镋S的fromsize一樣是會(huì)去遍歷的,所以會(huì)有同樣的問(wèn)題。

2.1 什么是深度分頁(yè)

分頁(yè)問(wèn)題是Elasticsearch中最常見(jiàn)的查詢(xún)場(chǎng)景之一,正常情況下分頁(yè)代碼如實(shí)下面這樣的:

# 查詢(xún)第一頁(yè)5條數(shù)據(jù)
GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 5  
}

輸出結(jié)果如下圖:
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
但是如果我們查詢(xún)的數(shù)據(jù)頁(yè)數(shù)特別大,當(dāng)from + size大于10000的時(shí)候,就會(huì)出現(xiàn)問(wèn)題,如下圖報(bào)錯(cuò)信息所示:
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
ES通過(guò)參數(shù)index.max_result_window用來(lái)限制單次查詢(xún)滿足查詢(xún)條件的結(jié)果窗口的大小,其默認(rèn)值為10000

2.2 深度分頁(yè)會(huì)帶來(lái)什么問(wèn)題

ES分頁(yè)查詢(xún)流程大致如下:

  1. 數(shù)據(jù)存儲(chǔ)在各個(gè)分片中,協(xié)調(diào)節(jié)點(diǎn)將查詢(xún)請(qǐng)求轉(zhuǎn)發(fā)給各個(gè)節(jié)點(diǎn),當(dāng)各個(gè)節(jié)點(diǎn)執(zhí)行搜索后,將排序后的前N條數(shù)據(jù)返回給協(xié)調(diào)節(jié)點(diǎn)
  2. 協(xié)調(diào)節(jié)點(diǎn)匯總各個(gè)分片返回的數(shù)據(jù),再次排序,最終返回前N條數(shù)據(jù)給客戶端
  3. 這個(gè)流程會(huì)導(dǎo)致一個(gè)深度分頁(yè)的問(wèn)題,也就是翻頁(yè)越多,性能越差,甚至導(dǎo)致ES出現(xiàn)OOM

在分布式系統(tǒng)中,對(duì)結(jié)果排序的成本隨分頁(yè)的深度成指數(shù)上升。

舉個(gè)例子:從10萬(wàn)名高考生中查詢(xún)成績(jī)?yōu)榈?0001-10100位的100名考生的信息,效果圖如下:
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
從上面案例中不難看出,每次有序的查詢(xún)都會(huì)在每個(gè)分片中執(zhí)行單獨(dú)的查詢(xún),然后進(jìn)行數(shù)據(jù)的二次排序,而這個(gè)二次排序的過(guò)程是發(fā)生在heap中的,也就是說(shuō)當(dāng)你單次查詢(xún)的數(shù)量越大,那么堆內(nèi)存中匯總的數(shù)據(jù)也就越多,對(duì)內(nèi)存的壓力也就越大。這里的單次查詢(xún)的數(shù)據(jù)量取決于你查詢(xún)的是第幾條數(shù)據(jù)而不是查詢(xún)了幾條數(shù)據(jù),比如你希望查詢(xún)的是第10001-10100這一百條數(shù)據(jù),但是ES必須將前10100全部取出進(jìn)行二次查詢(xún)。因此,如果查詢(xún)的數(shù)據(jù)排序越靠后,就越容易導(dǎo)致OOM(Out Of Memory)情況的發(fā)生,頻繁的深分頁(yè)查詢(xún)會(huì)導(dǎo)致頻繁的FGC
ES為了避免用戶在不了解其內(nèi)部原理的情況下而做出錯(cuò)誤的操作,設(shè)置了一個(gè)閾值,即max_result_window,其默認(rèn)值為10000,其作用是為了保護(hù)堆內(nèi)存不被錯(cuò)誤操作導(dǎo)致溢出。

2.3 深度分頁(yè)問(wèn)題的常見(jiàn)解決方案

2.3.1 嘗試避免使用深度分頁(yè)

很簡(jiǎn)單的道理,既然解決不了問(wèn)題,那就解決提出問(wèn)題的人。直接從業(yè)務(wù)上【嘗試避免使用深度分頁(yè)】。

解決深度分頁(yè)問(wèn)題最好的辦法就是避免使用深度分頁(yè)。谷歌、百度目前作為全球和國(guó)內(nèi)做大的搜索引擎不約而同的在分頁(yè)條中刪除了“跳頁(yè)”功能,其目的就是為了避免用戶使用深度分頁(yè)檢索。

【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
看看上面的截圖,有沒(méi)有發(fā)現(xiàn),他只有下一頁(yè),或者只能選擇最近10頁(yè),而不能直接跳到指定頁(yè)數(shù)。
這種做法,本質(zhì)上和ES中的max_result_window作用是一樣的

2.3.2 滾動(dòng)查詢(xún):Scroll Search(當(dāng)前已不推薦)

scroll滾動(dòng)搜索是先搜索一批數(shù)據(jù),然后下次再搜索下一批數(shù)據(jù),以此類(lèi)推,直到搜索出全部的數(shù)據(jù)來(lái)。
scroll搜索會(huì)在第一次搜索的時(shí)候,保存一個(gè)當(dāng)時(shí)的視圖快照,之后只會(huì)基于該視圖快照搜索數(shù)據(jù),如果在搜索期間數(shù)據(jù)發(fā)生了變更,用戶是看不到變更的數(shù)據(jù)的。因此,滾動(dòng)查詢(xún)不適合實(shí)時(shí)性要求高的搜索場(chǎng)景(官方已不推薦使用滾動(dòng)查詢(xún)進(jìn)行深度分頁(yè)查詢(xún),因?yàn)闊o(wú)法保存索引狀態(tài))

目前適合場(chǎng)景:?jiǎn)蝹€(gè)滾動(dòng)搜索請(qǐng)求中檢索大量結(jié)果,即非“C端業(yè)務(wù)”場(chǎng)景
使用示例:
1)第一次進(jìn)行scroll查詢(xún):

#查詢(xún)命令中新增scroll=1m,說(shuō)明采用游標(biāo)查詢(xún),保持游標(biāo)查詢(xún)窗口1分鐘,也就是本次快照的結(jié)果緩存起來(lái)的有效時(shí)間是1分鐘。
GET /es_db/_search?scroll=1m 
{
    "query": { "match_all": {}},
    "size":  2
}

查詢(xún)結(jié)果:除了返回前2條記錄,還返回了一個(gè)游標(biāo)ID值_scroll_id
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
2)從第二次查詢(xún)開(kāi)始,每次查詢(xún)都要指定_scroll_id參數(shù):

# scroll_id 的值就是上一個(gè)請(qǐng)求中返回的 _scroll_id 的值
GET /_search/scroll
{
    "scroll": "1m", 
    "scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFmNwcVdjblRxUzVhZXlicG9HeU02bWcAAAAAAABmzRY2YlV3Z0o5VVNTdWJobkE5Z3MtXzJB"
}

查詢(xún)結(jié)果:
【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java
多次根據(jù)scroll_id游標(biāo)查詢(xún),直到?jīng)]有數(shù)據(jù)返回則結(jié)束查詢(xún)。采用游標(biāo)查詢(xún)索引全量數(shù)據(jù),更安全高效,限制了單次對(duì)內(nèi)存的消耗。

正常來(lái)說(shuō)scroll超過(guò)超時(shí)后,搜索上下文會(huì)自動(dòng)刪除。然而,保持scroll打開(kāi)是有代價(jià)的,因此一旦不再使用,就應(yīng)明確清除scroll上下文

DELETE /_search/scroll
{
    "scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFmNwcVdjblRxUzVhZXlicG9HeU02bWcAAAAAAABmzRY2YlV3Z0o5VVNTdWJobkE5Z3MtXzJB"
}

注意事項(xiàng)

  • scroll滾動(dòng)查詢(xún)不適合實(shí)時(shí)性要求高的查詢(xún)場(chǎng)景,比較適合數(shù)據(jù)遷移的場(chǎng)景。
  • scroll查詢(xún)完畢后,要手動(dòng)清理掉 scroll_id 。雖然ES有自動(dòng)清理機(jī)制,但是 srcoll_id 的存在會(huì)耗費(fèi)大量的資源來(lái)保存一份當(dāng)前查詢(xún)結(jié)果集映像,并且會(huì)占用文件描述符。

官方建議:ES7之后,不再建議使用scroll API進(jìn)行深度分頁(yè)。如果要分頁(yè)檢索超過(guò) Top 10,000+ 結(jié)果時(shí),推薦使用:PIT + search_after

2.3.3 PIT + search_after

scroll API適用于高效的深度滾動(dòng),但滾動(dòng)上下文成本高昂,不建議將其用于實(shí)時(shí)用戶請(qǐng)求。而search_after參數(shù)通過(guò)提供一個(gè)活動(dòng)光標(biāo)來(lái)規(guī)避這個(gè)問(wèn)題。這樣可以使用上一頁(yè)的結(jié)果來(lái)幫助檢索下一頁(yè)。
search_after 分頁(yè)查詢(xún)可以簡(jiǎn)單概括為如下幾個(gè)步驟:

1)獲取索引的pit
使用 search_after 需要具有相同查詢(xún)和排序值的多個(gè)搜索請(qǐng)求。 如果在這些請(qǐng)求之間發(fā)生刷新,結(jié)果的順序可能會(huì)發(fā)生變化,從而導(dǎo)致跨頁(yè)面的結(jié)果不一致。 為防止出現(xiàn)這種情況,可以創(chuàng)建一個(gè)時(shí)間點(diǎn) (PIT) 以保留搜索中的當(dāng)前索引狀態(tài)。Point In Time(PIT)是 Elasticsearch 7.10 版本之后才有的新特性。

# 創(chuàng)建一個(gè)時(shí)間點(diǎn)(PIT)來(lái)保存搜索期間的當(dāng)前索引狀態(tài)
POST /es_db/_pit?keep_alive=1m
#返回結(jié)果,會(huì)返回一個(gè)PID的值
{
  "id" : "39K1AwEFZXNfZGIWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAWdkhjbE9YNVRTMUNDcWNQQVR2ZXYzdwAAAAAAAAA9jhZvaGpLSDlzVVMxbW5idG5DZ0xEUHFRAAEWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAA"
}

2) 根據(jù)pit首次查詢(xún)
根據(jù)pit查詢(xún)的時(shí)候,不用指定索引的名詞(畢竟前面創(chuàng)建PIT的時(shí)候已經(jīng)指定過(guò)了)

GET /_search
{
  "query": {
        "match_all": {}
    },
  "pit": {
        "id":  "39K1AwEFZXNfZGIWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAWdkhjbE9YNVRTMUNDcWNQQVR2ZXYzdwAAAAAAAAA9jhZvaGpLSDlzVVMxbW5idG5DZ0xEUHFRAAEWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAA", 
        "keep_alive": "1m"
  },
  "size": 2, 
  "sort": [
        {"_id": "asc"}    
    ]
}

返回結(jié)果:

{
  "pit_id" : "39K1AwEFZXNfZGIWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAWdkhjbE9YNVRTMUNDcWNQQVR2ZXYzdwAAAAAAAAA7hRZvaGpLSDlzVVMxbW5idG5DZ0xEUHFRAAEWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAA",
  "took" : 16,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : null,
        "_source" : {
          "name" : "李四",
          "sex" : 1,
          "age" : 28,
          "address" : "廣州荔灣大廈",
          "remark" : "java assistant"
        },
        "sort" : [
          "2",
          0
        ]
      },
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : null,
        "_source" : {
          "name" : "王五",
          "sex" : 0,
          "age" : 26,
          "address" : "廣州白云山公園",
          "remark" : "php developer"
        },
        "sort" : [
          "3",
          1
        ]
      }
    ]
  }
}

3)根據(jù)search_after和pit進(jìn)行翻頁(yè)查詢(xún)
要獲得下一頁(yè)結(jié)果,請(qǐng)使用最后一次命中的排序值(包括 tiebreaker)作為 search_after 參數(shù)重新運(yùn)行先前的搜索。 如果使用 PIT,請(qǐng)?jiān)?pit.id 參數(shù)中使用最新的 PIT ID。 搜索的查詢(xún)和排序參數(shù)必須保持不變。(這就跟我一開(kāi)始提到的mysql分頁(yè)優(yōu)化一樣的思路)

注意下面的search_after參數(shù)值:

#search_after指定為上一次查詢(xún)返回的sort值。
GET /_search
{
  "query": {
        "match_all": {}
    },
  "pit": {
        "id":  "39K1AwEFZXNfZGIWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAWdkhjbE9YNVRTMUNDcWNQQVR2ZXYzdwAAAAAAAAA9jhZvaGpLSDlzVVMxbW5idG5DZ0xEUHFRAAEWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAA", 
        "keep_alive": "1m"
  },
  "size": 2, 
  "sort": [
        {"_id": "asc"}    
    ],
  "search_after": [                                
    3
  ]
}

返回結(jié)果:

{
  "pit_id" : "39K1AwEFZXNfZGIWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAWdkhjbE9YNVRTMUNDcWNQQVR2ZXYzdwAAAAAAAAA8wxZvaGpLSDlzVVMxbW5idG5DZ0xEUHFRAAEWZTN2N2Nrdk5RRjY3QjBma1h5aFRodwAA",
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : null,
        "_source" : {
          "name" : "趙六",
          "sex" : 0,
          "age" : 22,
          "address" : "長(zhǎng)沙橘子洲",
          "remark" : "python assistant"
        },
        "sort" : [
          "4"
        ]
      },
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : null,
        "_source" : {
          "name" : "張龍",
          "sex" : 0,
          "age" : 19,
          "address" : "長(zhǎng)沙麓谷企業(yè)廣場(chǎng)",
          "remark" : "java architect assistant"
        },
        "sort" : [
          "5"
        ]
      }
    ]
  }
}

2.4 總結(jié)

【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn),tuling學(xué)院學(xué)習(xí)筆記,Java,elasticsearch,大數(shù)據(jù),搜索引擎,java

學(xué)習(xí)總結(jié)

  1. 學(xué)習(xí)了一些ES的簡(jiǎn)單查詢(xún)和復(fù)雜查詢(xún)

感謝

感謝【jc2182】網(wǎng)站出品的《ElasticSearch 教程》文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-735868.html

到了這里,關(guān)于【ES專(zhuān)題】ElasticSearch 高級(jí)查詢(xún)語(yǔ)法Query DSL實(shí)戰(zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • ES高級(jí)查詢(xún)語(yǔ)法DSL實(shí)戰(zhàn) - 第504篇

    ES高級(jí)查詢(xún)語(yǔ)法DSL實(shí)戰(zhàn) - 第504篇

    歷史文章( 文章 累計(jì)500+) 《國(guó)內(nèi)最全的Spring?Boot系列之一》 《國(guó)內(nèi)最全的Spring?Boot系列之二》 《國(guó)內(nèi)最全的Spring?Boot系列之三》 《國(guó)內(nèi)最全的Spring?Boot系列之四》 《國(guó)內(nèi)最全的Spring?Boot系列之五》 《國(guó)內(nèi)最全的Spring?Boot系列之六》 《國(guó)內(nèi)最全的Spring?Boot系列之七》 E

    2024年04月27日
    瀏覽(21)
  • 【ElasticSearch系列-03】ElasticSearch的高級(jí)句法查詢(xún)Query DSL

    【ElasticSearch系列-03】ElasticSearch的高級(jí)句法查詢(xún)Query DSL

    ElasticSearch系列整體欄目 內(nèi)容 鏈接地址 【一】ElasticSearch下載和安裝 https://zhenghuisheng.blog.csdn.net/article/details/129260827 【二】ElasticSearch概念和基本操作 https://blog.csdn.net/zhenghuishengq/article/details/134121631 【二】ElasticSearch的高級(jí)查詢(xún)Query DSL https://blog.csdn.net/zhenghuishengq/article/details/1

    2024年02月06日
    瀏覽(29)
  • elasticsearch 筆記二:搜索DSL 語(yǔ)法(搜索API、Query DSL)

    elasticsearch 筆記二:搜索DSL 語(yǔ)法(搜索API、Query DSL)

    從索引 tweet 里面搜索字段 user 為 kimchy 的記錄 從索引 tweet,user 里面搜索字段 user 為 kimchy 的記錄 從所有索引里面搜索字段 tag 為 wow 的記錄 說(shuō)明:搜索的端點(diǎn)地址可以是多索引多 mapping type 的。搜索的參數(shù)可作為 URI 請(qǐng)求參數(shù)給出,也可用 request body 給出 URI 搜索方式通過(guò) URI

    2024年02月04日
    瀏覽(18)
  • ElasticSearch級(jí)查詢(xún)Query DSL上

    ElasticSearch級(jí)查詢(xún)Query DSL上

    目錄 ES高級(jí)查詢(xún)Query DSL match_all 返回源數(shù)據(jù)_source 返回指定條數(shù)size 分頁(yè)查詢(xún)fromsize 指定字段排序sort 術(shù)語(yǔ)級(jí)別查詢(xún) Term query術(shù)語(yǔ)查詢(xún) Terms Query多術(shù)語(yǔ)查詢(xún) exists query ids query range query范圍查詢(xún) prefix query前綴查詢(xún) wildcard query通配符查詢(xún) fuzzy query模糊查詢(xún) ? ? ? ?ES中提供了一種強(qiáng)大

    2024年02月20日
    瀏覽(28)
  • ElasticSearch Index查詢(xún)(Query DSL)

    先貼一個(gè)Query DSL的官方文檔:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html 我平時(shí)喜歡查看官方文檔,了解數(shù)據(jù)查詢(xún)和存儲(chǔ)方面的性能優(yōu)化點(diǎn),下面是積累的腳本分享。 查詢(xún)語(yǔ)句格式 查詢(xún)類(lèi)型:match_all,match,term,range,fuzzy,bool 等等 查詢(xún)條件:查詢(xún)條件會(huì)根

    2024年02月07日
    瀏覽(23)
  • 15.Elasticsearch 7.15 Query DSL 之 Wildcard查詢(xún)、Regexp查詢(xún)

    返回包含與通配符模式匹配的文檔。 以下搜索返回 user.id 字段包含以 ki 開(kāi)頭并以 y 結(jié)尾的文檔。這些匹配項(xiàng)可以包括 kiy、kity 或 kimchy (必填, 對(duì)象) 你想查詢(xún)的字段 參數(shù)名 描述 boost (Optional, float) 用于降低或提高查詢(xún)相關(guān)性得分的浮點(diǎn)數(shù)。默認(rèn)為1.0。 rewrite (可選,字符串)

    2023年04月08日
    瀏覽(36)
  • 【DSL】ES+DSL 查詢(xún)語(yǔ)法

    一、前言 工作中遇到ES的查詢(xún)問(wèn)題,由于業(yè)務(wù)方給的條件不清晰,有些查詢(xún)無(wú)法實(shí)現(xiàn),需要用到DSL語(yǔ)法查詢(xún)實(shí)現(xiàn),很久沒(méi)用生疏了,借此機(jī)會(huì)復(fù)習(xí)下。 二、定義 1.基本介紹 Elasticsearch(簡(jiǎn)稱(chēng)為ES ),一個(gè)開(kāi)源的分布式搜索和分析引擎,主要用于處理大量數(shù)據(jù)并提供快速、實(shí)時(shí)

    2024年02月12日
    瀏覽(24)
  • 【ElasticSearch】DSL查詢(xún)語(yǔ)法

    【ElasticSearch】DSL查詢(xún)語(yǔ)法

    Elasticsearch提供了基于JSON的DSL(Domain Specific Language)來(lái)定義查詢(xún)。官方文檔: 其中,常見(jiàn)的查詢(xún)類(lèi)型有: 查詢(xún)所有 :查詢(xún)出所有數(shù)據(jù),一般測(cè)試用。例如: 全文檢索(full text)查詢(xún) :利用分詞器對(duì)用戶輸入內(nèi)容分詞,然后去倒排索引庫(kù)中匹配。例如: 精確查詢(xún) :根據(jù)精確

    2024年02月16日
    瀏覽(21)
  • ElasticSearch - DSL查詢(xún)語(yǔ)法

    ElasticSearch - DSL查詢(xún)語(yǔ)法

    目錄 DSL查詢(xún)分類(lèi) 全文檢索查詢(xún) 精確查詢(xún) 地理查詢(xún) 復(fù)合查詢(xún) 相關(guān)性算分 算分函數(shù)查詢(xún) BooleanQuery DSL查詢(xún)分類(lèi) Elasticsearch提供了基于JSON的DSL(Domain Specific Language)來(lái)定義查詢(xún) 常見(jiàn)的查詢(xún)類(lèi)型包括: 查詢(xún)所有:查詢(xún)出所有的數(shù)據(jù),一般測(cè)試用;例如:match_all 全文檢索(full text)查詢(xún)

    2023年04月08日
    瀏覽(41)
  • ElasticSearch - DSL查詢(xún)文檔語(yǔ)法,以及深度分頁(yè)問(wèn)題、解決方案

    ElasticSearch - DSL查詢(xún)文檔語(yǔ)法,以及深度分頁(yè)問(wèn)題、解決方案

    目錄 一、DSL 查詢(xún)文檔語(yǔ)法 前言 1.1、DSL Query 基本語(yǔ)法 1.2、全文檢索查詢(xún) 1.2.1、match 查詢(xún) 1.2.2、multi_match 1.3、精確查詢(xún) 1.3.1、term 查詢(xún) 1.3.2、range 查詢(xún) 1.4、地理查詢(xún) 1.4.1、geo_bounding_box 1.4.2、geo_distance 1.5、復(fù)合查詢(xún) 1.5.1、相關(guān)性算分 1.5.2、function_score 1.5.3、boolean query 1.6、搜索

    2024年02月07日
    瀏覽(25)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包