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