官網(wǎng)連接:
https://www.elastic.co/guide/en/elasticsearch/reference/7.10/query-filter-context.html
Query DSL(Domain Specific Language)
- query string search
- 全文檢索-fulltext search
- 精準(zhǔn)匹配-term match
- 過濾器-filter
- 組合查詢-bool query
1 查詢上下文
? 使用query關(guān)鍵字進(jìn)行檢索,傾向于相關(guān)度搜索,故需要計算評分。搜索是Elasticsearch最關(guān)鍵和重要的部分。
GET product/_search
#這兩個的查詢是等效的
GET product/_search
{
"query": {
"match_all": {}
}
}
2 相關(guān)度評分:_score
? 概念:相關(guān)度評分用于對搜索結(jié)果排序,評分越高則認(rèn)為其結(jié)果和搜索的預(yù)期值相關(guān)度越高,即越符合搜索預(yù)期值。在7.x之前相關(guān)度評分默認(rèn)使用TF/IDF算法計算而來,7.x之后默認(rèn)為BM25。在核心知識篇不必關(guān)心相關(guān)評分的具體原理,只需知曉其概念即可。
? 排序:相關(guān)度評分為搜索結(jié)果的排序依據(jù),默認(rèn)情況下評分越高,則結(jié)果越靠前。
GET product/_search
{
"query": {
"match": {
"name": "xiaomi"
}
}
}
結(jié)果:可以看到_score是倒序的
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.72615415,
"hits" : [
{
"_index" : "product",
"_type" : "_doc",
"_id" : "4",
"_score" : 0.72615415,
"_source" : {
"name" : "xiaomi erji",
"desc" : "erji zhong de huangmenji",
"price" : 999,
"tags" : [
"low",
"bufangshui",
"yinzhicha"
]
}
},
{
"_index" : "product",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.60996956,
"_source" : {
"name" : "xiaomi nfc phone",
"desc" : "zhichi quangongneng nfc,shouji zhong de jianjiji",
"price" : 4999,
"tags" : [
"xingjiabi",
"fashao",
"gongjiaoka"
]
}
}
]
}
}
3 元數(shù)據(jù):_source
-
禁用_source:
-
好處:節(jié)省存儲開銷
-
壞處:
- 不支持update、update_by_query和reindex API。
- 不支持高亮。
- 不支持reindex、更改mapping分析器和版本升級。
- 通過查看索引時使用的原始文檔來調(diào)試查詢或聚合的功能。
- 將來有可能自動修復(fù)索引損壞。
總結(jié):如果只是為了節(jié)省磁盤,可以壓縮索引比禁用_source更好。
-
-
數(shù)據(jù)源過濾器:
Including:結(jié)果中返回哪些field
Excluding:結(jié)果中不要返回哪些field,不返回的field不代表不能通過該字段進(jìn)行檢索,因為元數(shù)據(jù)不存在不代表索引不存在
-
在mapping中定義過濾:支持通配符,但是這種方式不推薦,因為mapping不可變
PUT product2 { "mappings": { "_source": { "includes": [ "name", "price" ], "excludes": [ "desc", "tags" ] } } } PUT /product2/_doc/1 { "name": "hongmi erji", "desc": "erji zhong de kendeji", "price": 399, "tags": ["lowbee","xuhangduan","zhiliangx"] } GET product2/_search #結(jié)果,只展示了name\price
-
常用過濾規(guī)則
- “_source”: “false”,
- “_source”: “obj.*”,
- “_source”: [ “obj1.*”, “obj2.*” ],
- “_source”: {
“includes”: [ “obj1.*”, “obj2.*” ],
“excludes”: [ “*.description” ]
}
DELETE product2 PUT /product2/_doc/1 { "owner":{ "name":"zhangsan", "sex":"男", "age":18 }, "name": "hongmi erji", "desc": "erji zhong de kendeji", "price": 399, "tags": ["lowbee","xuhangduan","zhiliangx"] } GET product2/_search GET product2/_search { "_source": false, #查詢結(jié)果,不顯示_source "_source": "name", "_source": "owner", "_source": "owner.*", "_source": "owner.name", "_source": ["owner.name","owner.age"], #如果includes和excludes沒有交集,此時查詢結(jié)果只顯示name\price,查詢結(jié)果以includes為準(zhǔn),此時owner屬性是沒有寫到excludes里邊的,此時excludes不寫也是可以的 #如果includes和excludes有了交集,如excludes里邊也有name,此時查詢結(jié)果只顯示price "_source": { "includes": [ "name", "price" ], "excludes": [ "desc", "tags" ] }, "query": { "match_all": {} } }
-
4 query string search
#查詢所有
GET /product/_search
#帶參數(shù),name里邊包含xiaomi的
GET /product/_search?q=name:xiaomi
#分頁
GET /product/_search?from=0&size=2&sort=price:asc
#在每條數(shù)據(jù)里邊加入date字段
#精準(zhǔn)匹配 exact value,只會匹配date為2021-06-01的數(shù)據(jù)
GET /product/_search?q=date:2021-06-01
#_all搜索 相當(dāng)于在所有有索引的字段中檢索(默認(rèn)都是創(chuàng)建了倒排索引),會匹配內(nèi)容包含2021-06-01的數(shù)據(jù),結(jié)果為date\desc里有2021-06-01的數(shù)據(jù)
GET /product/_search?q=2021-06-01
#我們不想匹配desc里的怎么辦?把它的索引關(guān)掉
#1.刪掉product
DELETE product
#2.創(chuàng)建索引映射,關(guān)掉desc的索引
PUT product
{
"mappings": {
"properties": {
"desc": {
"type": "text",
"index": false
}
}
}
}
#3.插入還是剛才的那些數(shù)據(jù)
#4.再次查詢,結(jié)果只有date的數(shù)據(jù)
GET /product/_search?q=2021-06-01
#恢復(fù)原來的數(shù)據(jù),刪掉product、插入還是剛才的那些數(shù)據(jù)
#發(fā)現(xiàn)查詢到了desc里邊包含01的數(shù)據(jù),而沒有date的數(shù)據(jù),說明desc的數(shù)據(jù)被分詞了
GET /product/_search?q=01
DELETE product
PUT /product/_doc/1
{
"name" : "xiaomi phone",
"desc" : "shouji zhong de zhandouji",
"date": "2021-06-01",
"price" : 3999,
"tags": [ "xingjiabi", "fashao", "buka" ]
}
PUT /product/_doc/2
{
"name" : "xiaomi nfc phone",
"desc" : "zhichi quangongneng nfc,shouji zhong de jianjiji",
"date": "2021-06-02",
"price" : 4999,
"tags": [ "xingjiabi", "fashao", "gongjiaoka" ]
}
PUT /product/_doc/3
{
"name" : "nfc phone",
"desc" : "shouji zhong de hongzhaji",
"date": "2021-06-03",
"price" : 2999,
"tags": [ "xingjiabi", "fashao", "menjinka" ]
}
PUT /product/_doc/4
{
"name" : "xiaomi erji",
"desc" : "erji zhong de huangmenji",
"date": "2021-04-15",
"price" : 999,
"tags": [ "low", "bufangshui", "yinzhicha" ]
}
PUT /product/_doc/5
{
"name" : "hongmi erji",
"desc" : "erji zhong de kendeji 2021-06-01",
"date": "2021-04-16",
"price" : 399,
"tags": [ "lowbee", "xuhangduan", "zhiliangx" ]
}
5 全文檢索-fulltext search
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-cSJj1ZUr-1682735356029)(01-核心知識篇.assets/image-20230415123708817.png)]
用戶請求會被分詞
-
match:匹配包含某個term的子句
-
match_all:匹配所有結(jié)果的子句
-
multi_match:多字段條件
-
match_phrase:短語查詢,
#DSL
#match ,請求會被分詞,分成了xiaomi、phone詞相
#包含 xiaomi 或者 phone 的結(jié)果都會被命中
GET product/_search
{
"query": {
"match": {
"name": "xiaomi phone"
}
}
}
#match_all,查詢所有數(shù)據(jù)
GET product/_search
{
"query": {
"match_all": {}
}
}
#multi_match,在fields字段里邊包含了query
#name中包含了phone 或 huangmenji
#desc中包含了phone 或 huangmenji
#where a=xx or b=xx
GET product/_search
{
"query": {
"multi_match": {
"query": "phone huangmenji",
"fields": ["name","desc"]
}
}
}
#match_phrase
#這里的短語不會被分詞,必須包含 xiaomi 和 nfc 兩個詞項,并且順序還要相同,并且兩個詞項之間不能包含其他詞項。注意 短語查詢并不是直接包含 xiaomi nfc 這個短語
GET product/_search
{
"query": {
"match_phrase": {
"name": "xiaomi nfc"
}
}
}
6 精準(zhǔn)匹配-term match
-
term:匹配和搜索詞項完全相等的結(jié)果
-
term和match_phrase區(qū)別:
match_phrase 會將檢索關(guān)鍵詞分詞, match_phrase的分詞結(jié)果必須在被檢索字段的分詞中都包含,而且順序必須相同,而且默認(rèn)必須都是連續(xù)的
term搜索不會將搜索詞分詞
-
term和keyword區(qū)別
term是對于搜索詞不分詞,
keyword是字段類型,是對于source data中的字段值不分詞
-
terms:匹配和搜索詞項列表中任意項匹配的結(jié)果
-
range:范圍查找
#沒結(jié)果
GET product/_search
{
"query": {
"term": {
"name": "xiaomi phone"
}
}
}
#有結(jié)果。被檢索字段里必須包含這里的每一個詞項,且順序一致,
GET product/_search
{
"query": {
"match_phrase": {
"name": "xiaomi phone"
}
}
}
#有結(jié)果
GET product/_search
{
"query": {
"term": {
"name.keyword": "xiaomi phone"
}
}
}
#查詢tags里邊包含lowbee\gongjiaoka
GET product/_search
{
"query": {
"terms": {
"tags": [
"lowbee",
"gongjiaoka"
]
}
}
}
#gt是>,gte是>=,lt是<,lte是<=
GET product/_search
{
"query": {
"range": {
"price": {
"gte": 399,
"lte": 2999
}
}
}
}
GET product/_search
{
"query": {
"range": {
"date": {
"gte": "2021-04-15",
"lte": "2021-04-16"
}
}
}
}
#date里邊也可以加時區(qū)
#now-1d/d 當(dāng)前時間減一天,單位是天
#now/d 當(dāng)前時間,單位是天
GET product/_search
{
"query": {
"range": {
"date": {
"gte": "now-1d/d",
"lte": "now/d"
}
}
}
}
7 過濾器-filter
GET _search
{
"query": {
"constant_score": {
"filter": {
"term": {
"status": "active"
}
}
}
}
}
query和filter的主要區(qū)別在: filter是結(jié)果導(dǎo)向的而query是過程導(dǎo)向。
query傾向于“當(dāng)前文檔和查詢的語句的相關(guān)度”,而filter傾向于“當(dāng)前文檔和查詢的條件是不是相符”。即在查詢過程中,query是要對查詢的每個結(jié)果計算相關(guān)性得分的(_score,倒序的),而filter不會。另外filter有相應(yīng)的緩存機(jī)制,可以提高查詢效率。
例子,比如查詢10萬數(shù)據(jù),按照age排序,不使用filter的時候,是按照_score倒序的;可以使用filter先把數(shù)據(jù)過濾出來,之后再排序。
#_score,倒序的
GET product/_search
{
"query": {
"term": {
"name": "phone"
}
}
}
#_score固定的,沒有給定的話就是1.0,可以使用boost給定分?jǐn)?shù)
GET product/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"name": "phone"
}
},
"boost": 1.2
}
}
}
#bool里邊也可以嵌套filter
GET product/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"name": "phone"
}
}
]
}
}
}
8 組合查詢-bool query
bool:可以組合多個查詢條件,bool查詢也是采用more_matches_is_better的機(jī)制,因此滿足must和should子句的文檔將會合并起來計算分值文章來源:http://www.zghlxwxcb.cn/news/detail-447383.html
- must:必須滿足子句(查詢)必須出現(xiàn)在匹配的文檔中,并將有助于得分。
- filter:過濾器 不計算相關(guān)度分?jǐn)?shù),cache☆子句(查詢)必須出現(xiàn)在匹配的文檔中。但是不像 must查詢的分?jǐn)?shù)將被忽略。Filter子句在filter上下文中執(zhí)行,這意味著計分被忽略,并且子句被考慮用于緩存。
- should:可能滿足 or子句(查詢)應(yīng)出現(xiàn)在匹配的文檔中。
- must_not:必須不滿足 ,不計算相關(guān)度分?jǐn)?shù) not子句(查詢)不得出現(xiàn)在匹配的文檔中。子句在過濾器上下文中執(zhí)行,這意味著計分被忽略,并且子句被視為用于緩存。由于忽略計分,0因此將返回所有文檔的分?jǐn)?shù)。
minimum_should_match:參數(shù)指定should返回的文檔必須匹配的子句的數(shù)量或百分比。如果bool查詢包含至少一個should子句,而沒有must或 filter子句,則默認(rèn)值為1。否則,默認(rèn)值為0文章來源地址http://www.zghlxwxcb.cn/news/detail-447383.html
#must計算出來的_score是不一樣的,倒序
#查詢name包含xiaomi\phone,且desc包含shouji zhong
GET product/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "xiaomi phone"
}
},
{
"match_phrase": {
"desc": "shouji zhong"
}
}
]
}
}
}
#filter計算出來的_score都是0.0
#查詢name包含xiaomi\phone,且desc包含shouji zhong
GET product/_search
{
"query": {
"bool": {
"filter": [
{
"match": {
"name": "xiaomi phone"
}
},
{
"match_phrase": {
"desc": "shouji zhong"
}
}
]
}
}
}
#must_not計算出來的_score都是0.0
#查詢name包含xiaomi\nfc,且price>=500 的對立面
GET product/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"name": "xiaomi nfc"
}
},
{
"range": {
"price": {
"gte": 500
}
}
}
]
}
}
}
#should
#相當(dāng)于or,查詢條件就是可以滿足0個,1個,多個
GET product/_search
{
"query": {
"bool": {
"should": [
{
"match_phrase": {
"name": "xiaomi nfc"
}
},
{
"range": {
"price": {
"lte": 500
}
}
}
]
}
}
}
#組合查詢
#單獨用must結(jié)果是1、2、4
#單獨用filter結(jié)果是4、5
#must+filter結(jié)果4(交集是4)
#must與filter是 and 的關(guān)系
#為什么不把filter的條件寫在must里邊呢?
#must是要進(jìn)行相關(guān)度分?jǐn)?shù)計算的。先在filter中進(jìn)行過濾(此時是不進(jìn)行相關(guān)度分?jǐn)?shù)的計算的),之后再用must。filter減少了計算,而且有緩存
GET product/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "xiaomi"
}
}
],
"filter": [
{
"range": {
"price": {
"lte": 1000
}
}
}
]
}
}
}
#單獨用should結(jié)果是1、2、3、4、5
#單獨用filter結(jié)果是2、3
#should+filter結(jié)果1、2、3、4、5
#因為此時should子句可以滿足的數(shù)量是0,
#此時設(shè)置minimum_should_match為1,表示should子句可以滿足的數(shù)量是1,執(zhí)行結(jié)果就是2、3了
#可以多加幾個should子句
#should子句里邊也可以再包含bool子句
GET product/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"price": {
"lte": 10000
}
}
}
],
"should": [
{
"match_phrase": {
"name": "nfc phone"
}
}
]
}
}
}
到了這里,關(guān)于(5)elasticsearch的Query DSL的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!