Query DSL
Es提供了基於JSON的完整查詢DSL(Domain Specific Language 特定域的語言)來定義查詢。將查詢DSL視為查詢的AST(抽象語法樹)。它由兩種子句組成:
- 葉子查詢子句
葉子查詢子句,在特定域中尋找特定的值,如match、term或range查詢
- 複合查詢子句
複合查詢子句包裝其他葉子查詢或複合查詢,並用於以邏輯方式組合多個查詢。如bool、dis_max、constant_score查詢
1. 查詢所有
POST /索引名稱/_search
{
"query":{
"match_all": {}
}
}
查詢結果示例:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test-demo1",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"name" : "百度3",
"job" : "運營",
"amt" : "3000.34",
"logo" : "http://www.lgstatic.com/ttasdf2",
"createTime" : "20220303230000"
}
}
...省略2條資料
]
}
}
- took:查詢花費時間,單位是毫秒
- time_out:是否超時
- _shards:分片資訊
- hits:搜尋結果總覽物件
- total:搜尋到的總條數
- max_score:所有結果中文件得分的最高分
- hits:搜尋結果的文件物件陣列,每個元素是一條搜尋到的文件資訊
- _index:索引庫
- _type:文件型別
- _id:文件id
- _score:文件得分
- _source:文件的源資料
2. 全文搜尋
全文搜尋能夠搜尋已分析的文字欄位,如電子郵件正文、商品描述等。
先造一些測試資料:
PUT /item
{
"settings": {},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"images": {
"type": "keyword"
},
"price": {
"type": "float"
}
}
}
}
POST /item/_doc/
{
"title": "小米電視4A",
"images": "http://image.lagou.com/12479122.jpg",
"price": 4288
}
POST /item/_doc/
{
"title": "小米手機",
"images": "http://image.lagou.com/12479122.jpg",
"price": 2688
}
POST /item/_doc/
{
"title": "蘋果手機",
"images": "http://image.lagou.com/12479122.jpg",
"price": 5699
}
2.1 匹配搜尋
- or關係
match型別的查詢,會把查詢條件分詞,多個詞條之間是or的關係。如下面的例子,會根據小米和手機分別去搜尋,能搜出3條資料。
POST /item/_search
{
"query":{
"match": {
"title": "小米手機"
}
}
}
- and關係
POST /item/_search
{
"query":{
"match": {
"title": {
"query": "小米手機",
"operator":"and"
}
}
}
}
2.2 短語搜尋
match_phrase查詢用來對一個欄位進行短語查詢,可以指定analyzer、slop移動因子
POST /item/_search
{
"query":{
"match_phrase": {
"title": "小米手機"
}
}
}
帶slop:
POST /item/_search
{
"query":{
"match_phrase": {
"title": {
"query": "手機小米",
"slop":2
}
}
}
}
slop引數告訴match_phrase查詢詞條能夠相隔多遠時仍然將文件視為匹配。相隔多遠的意思是,你需要移動一個詞條多少次來讓查詢和文件匹配
2.3 query_string 查詢
query string提供了無需指定某欄位而對文件全文進行匹配查詢的一個高階查詢,同時可以指定在哪些欄位上進行匹配。
GET /item/_search
{
"query": {
"query_string": {
"query": "2688"
}
}
}
GET /item/_search
{
"query": {
"query_string": {
"default_field": "price",
"query": "2688"
}
}
}
GET /item/_search
{
"query": {
"query_string": {
"default_field": "title",
"query": "手機 OR 小米"
}
}
}
GET /item/_search
{
"query": {
"query_string": {
"default_field": "title",
"query": "手機 and 小米"
}
}
}
#模糊查詢
GET /item/_search
{
"query": {
"query_string": {
"default_field": "title",
"query": "小米~1"
}
}
}
#多欄位支援
GET /item/_search
{
"query": {
"query_string": {
"fields": ["title","price"],
"query": "2699"
}
}
}
2.4 多欄位匹配搜尋
如果你需要在多個欄位上進行文字搜尋,可用multi_match。
GET /item/_search
{
"query": {
"multi_match": {
"query": "2688",
"fields": ["title","price"]
}
}
}
#還可以使用*配置
GET /item/_search
{
"query": {
"multi_match": {
"query": "2688",
"fields": ["title","pri*"]
}
}
}
3. 詞條搜尋
可以使用term-level queries根據結構化資料中的精確值查詢文件。term-level queries不分析搜尋詞。搜尋詞與儲存在欄位中的詞需要完全匹配
3.1 詞條普通搜尋
用於查詢指定欄位包含某個搜尋詞的文件
POST /item/_search
{
"query": {
"term": {
"title":"小米"
}
}
}
3.2 詞條集合搜尋
POST /item/_search
{
"query": {
"terms": {
"title": ["小米","電視"]
}
}
}
3.3 範圍搜尋
- gte:大於等於
- gt:大於
- lte:小於等於
- lt:小於
- boost:查詢權重
POST /item/_search
{
"query": {
"range": {
"price": {
"gte": 10,
"lte": 3000
}
}
}
}
#日期範圍
POST /item/_search
{
"query": {
"range": {
"createTime": {
"gte": "2022-01-01",
"lte": "2022-02-01",
"format": "yyyy-MM-dd"
}
}
}
}
3.4 不為空搜尋
GET /item/_search
{
"query": {
"exists": {
"field": "price"
}
}
}
3.5 詞項字首搜尋
GET /item/_search
{
"query": {
"prefix": {
"title": {
"value": "小米"
}
}
}
}
3.6 萬用字元搜尋
GET /item/_search
{
"query": {
"wildcard": {
"title":"小*"
}
}
}
3.7 正則搜尋
GET /item/_search
{
"query": {
"regexp": {
"title":"小米[a-z0-9]"
}
}
}
3.8 模糊搜尋
GET /item/_search
{
"query": {
"fuzzy": {
"title": "手機"
}
}
}
#錯別字糾正
GET /item/_search
{
"query": {
"fuzzy": {
"title": {
"value": "大米",
"fuzziness": 1
}
}
}
}
3.9 ids搜尋
GET /item/_search
{
"query": {
"ids": {
"values": ["t76YgYEB9TD2fYkcLzha","tb6XgYEB9TD2fYkc6zhx"]
}
}
}
4. 複合搜尋
4.1 constant_score,用來包裝另一個查詢,將查詢匹配的文件的評分設為一個常值
GET /item/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"title": "小米"
}
},
"boost": 1.2
}
}
}
4.2 bool query,用bool組合多個查詢子句為一個查詢。
- must:必須滿足
- filter:必須滿足,但執行的是filter上下文,不參與、影響評分
- should:或
- must_not:必須不滿足,在filter上下文中執行,不參與、不影響評分
POST /item/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "小米"
}
}
], "filter": {
"term": {
"title": "電視"
}
},"must_not": [
{
"range": {
"price": {
"gte": 4200,
"lte": 4300
}
}
}
]
,"minimum_should_match": 0
}
}
}
minimum_should_match代表了最小匹配精度,如果設定為1,代表should語句中至少需要有一個條件滿足。
5. 排序
5.1 相關性評分排序
預設情況下,返回的結果是按照相關性進行排序的。預設排序是_score降序
# 按照評分升序
GET /item/_search
{
"query": {
"match_all": {}
},
"sort":[{
"_score":{
"order":"asc"
}
}
]
}
#根據欄位值排序
GET /item/_search
{
"query": {
"match_all": {}
},
"sort":[{
"price":{
"order":"asc"
}
}
]
}
#多個欄位的排序
GET /item/_search
{
"query": {
"match_all": {}
},
"sort":[{
"price":{
"order":"asc"
}
},{
"createTime": {
"order":"desc"
}
}
]
}
6.分頁
size:每頁顯示多少條
from:當前頁起始索引
POST /item/_search
{
"query": {
"match_all": {}
}
,"size": 2,
"from": 0
}
7. 高亮
POST /item/_search
{
"query": {
"match": {
"title": "小米"
}
},
"highlight": {
"pre_tags": "<font color='pink'>",
"post_tags": "</font>",
"fields": [{"title":{}}]
}
}
- pre_tags:前置標籤
- post_tags:後置標籤
- fields:需要高亮的欄位
- title:這裡宣告title欄位需要高亮
8. 文件批量操作
8.1 mget批量查詢
不同的索引
GET /_mget
{
"docs":[
{
"_index":"item",
"_id":"tb6XgYEB9TD2fYkc6zhx"
},
{
"_index":"test-location",
"_id":1
}
]
}
相同的索引
POST /test-location/_search
{
"query": {
"ids": {
"values": ["1","2"]
}
}
}
8.2 bulk批量增刪改
語法:
POST /_bulk
{"action": {"metadata"}}
{"data"}
示例:
POST /_bulk
{"delete":{"_index":"item","_id":"tb6XgYEB9TD2fYkc6zhx"}}
{"create":{"_index":"item","_id":"1"}}
{"title":"華為電腦","price":2333}
{"update":{"_index":"item","_id":2}}
{"doc":{"title":"冰箱"}}
- delete:刪除一個文件,刪除沒有請求體,只需要一個json串就行
- create:相當於強制建立
- index:普通的PUT操作,可以建立也可以全量替換
- update:執行的是區域性更新
格式:每個json不能換行,相鄰json必須換行
隔離:每個操作互不影響,操作失敗的行會返回其失敗資訊
實際用法:bulk請求一次不要太大,否則一下積壓到記憶體中,效能會下降。所以,一次請求幾千個操作、大小在幾M正好。bulk會將要處理的資料載入記憶體中,所以資料量是有限的,最佳的資料量不是一個確定的資料,它取決於你的硬體,你的文件大小以及複雜性,你的索引以及搜尋的負載。一般建議是1000-5000個文件,大小建議是5-15MB,預設不能超過100M,可以在es的配置檔案(ES的config下的elasticsearch.yml)中配置。
http.max_content_length: 10mb