巧記Elasticsearch常用DSL語法
記知識先記輪廓,關于DSL語法的輪廓,記住以下三句話即可:
- 索引、文檔和查詢
- Match、Term和Bool
- 還有翻頁和聚合
一、又愛又恨的DSL
使用Elasticsearch時,我們一般是調用RestClient API的方式讀取和寫入集群數據。有時也會使用工具查閱和操作數據,比如:使用Chrome插件Multi Elasticsearch Head或者Cerebro、Kibana。筆者建議使用Kibana的方式操作集群數據,使用Multi Elasticsearch Head或者Cerebro從整體上觀察集群。
既然是操作集群數據,那就繞不開ES的DSL語法 — 一個讓人又愛又恨的語法。
- 愛:Http Restful風格設計的,使用上簡單,隨手擼起一個工具都支持Http訪問。
- 恨:語法太難記,語法格式在設計上有點反人類,真不知道設計者們是怎么想的。不過你覺得有更好的方案嗎?
本文整理了一些常用DSL語法,方便記憶,分了如下幾類:操作索引、操作文檔、Match查詢、Term查詢、查看分詞。如果碰到復雜查詢還是建議查閱官網。
二、操作數據
在Kibana上操作ES數據的方式如下:
1.操作索引
(1) 創建索引:
PUT /goods
{
"mappings": {
"properties": {
"brandName": {
"type": "keyword"
},
"categoryName": {
"type": "keyword"
},
"createTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"id": {
"type": "keyword"
},
"price": {
"type": "double"
},
"saleNum": {
"type": "integer"
},
"status": {
"type": "integer"
},
"stock": {
"type": "integer"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
},
# 根據情況選擇是否要修改
"settings": {
"number_of_shards": 2,
"number_of_replicas": 2
}
}
(2) 刪除索引:
DELETE goods
(3) 重建索引
有些場景下需要重建索引,比如修改了Mapping,重建步驟如下:
POST _reindex
{
"source": {
"index": "goods"
},
"dest": {
"index": "goods1"
}
}
DELETE goods
POST _reindex
{
"source": {
"index": "goods1"
},
"dest": {
"index": "goods"
}
}
DELETE goods1
2.操作文檔
(1) 創建文檔
# 這種方式,同樣的id無法重新創建
PUT goods/_create/1
{
"id": 1,
"brandName": "Apple",
"categoryName": "手機",
"createTime": "2023-10-22 19:12:56",
"price": 8799,
"saleNum": 599,
"status": 0,
"stock": 1000,
"title": "Apple iPhone 15 Pro 512GB 遠峰藍色 支持移動聯通電信5G 雙卡雙待手機"
}
# 這種方式,同樣的id會覆蓋原有的
PUT goods/_doc/2
{
"id": 2,
"brandName": "Apple",
"categoryName": "手機",
"createTime": "2023-10-22 19:12:56",
"price": 8799,
"saleNum": 599,
"status": 0,
"stock": 1000,
"title": "Apple iPhone 15 Pro 256GB 遠峰藍色 支持移動聯通電信5G 雙卡雙待手機"
}
(2) 更新文檔
POST goods/_update/1
{
"doc": {
"title":"Apple iPhone 13 Pro (A2639) 256GB 遠峰藍色 支持移動聯通電信5G 雙卡雙待手機111"
}
}
(3) 刪除文檔
DELETE goods/_doc/2
(4) 獲取文檔
# 獲取單個文檔
GET goods/_doc/1
# 批量獲取
GET books/_doc/_mget
{
"ids": ["1","2"]
}
2.Match查詢
Match查詢會對查詢內容做分詞,然后根據倒排索引去匹配文檔。Term查詢對查詢內容不做分詞,直接去倒排索引里去匹配文檔。
(1) 查詢所有
POST goods/_search
{
"query": {
"match_all": {
}
}
}
(2) match_phrase短語查詢
POST goods/_search
{
"query": {
"match_phrase": {
"title": "支持"
}
}
}
(3) 匹配查詢
POST goods/_search
{
"query": {
"match": {
"title": "移動多余"
}
}
}
(4) 模糊匹配查詢
POST goods/_search
{
"query": {
"wildcard": {
"title": {
"value": "*鞋"
}
}
}
}
4.Term查詢
Term查詢對查詢內容不做分詞,直接去倒排索引里去匹配文檔。
POST goods/_search
{
"query": {
"term": {
"title": {
"value": "手機"
}
}
}
}
# 匹配多個term
POST goods/_search
{
"query": {
"terms": {
"title": [
"雙卡",
"待"
]
}
}
}
5.組合查詢
復雜查詢基本會用到bool關鍵字。
(1) bool + must
# 布爾查詢,可以組合多個過濾語句來過濾文檔
POST goods/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"title": {
"value": "Wolfgang Mauerer"
}
}
},
{
"term": {
"date": {
"value": "2010-06-01"
}
}
}
]
}
}
}
# 匹配多個字段
GET product/_search
{
"query": {
"bool": {
"must": [
{ "match_phrase": { "name": "連衣裙" } },
{ "match_phrase": { "en_intro": "korean" } },
{ "match_phrase": { "intro": "御姐" } }
]
}
}
}
(2) bool + filter + range
POST books/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"author": {
"value": "Wolfgang Mauerer"
}
}
}
],
"filter": [
{
"term": {
"date": {
"value": "2010-06-01"
}
}
}
]
}
}
}
POST goods/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "華為"
}
}
],
"filter": [
{
"range": {
"price": {
"gte": 5000,
"lte": 10000
}
}
}
]
}
}
}
6.翻頁查詢
(1) Scroll分頁
# 第一次使用 scroll API
POST goods/_search?scroll=2m
{
"query": {
"match_all": {}
},
"size": 2
}
# 進行翻頁
POST /_search/scroll
{
"scroll" : "2m",
"scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFkxBWkYwOGw2U1dPSF94aHZTelFkaWcAAAAAAAADHhZoU05ERFl3WFIycXM3M3JKMmRQVkJB"
}
(2) from + size分頁
POST goods/_search
{
"query": {
"match_all": {
}
},
"from": 6,
"size": 2,
"sort": [
{
"price": {
"order": "asc"
}
}
]
}
7.聚合查詢
(1) 最大、最小、平均
POST goods/_search
{
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
POST goods/_search
{
"aggs": {
"min_price": {
"min": {
"field": "price"
}
}
}
}
POST goods/_search
{
"aggs": {
"max_price": {
"max": {
"field": "price"
}
}
}
}
(2) 范圍查詢
POST goods/_search
{
"query": {
"range": {
"price": {
"gte": 10,
"lte": 20
}
}
}
}
(3) 高亮查詢
POST goods/_search
{
"query": {
"match": {
"title": "跑鞋"
}
},
"highlight": {
"fields": {
"body": {
"pre_tags": [
"<font color='red'>"
],
"post_tags": [
"</font>"
]
},
"title": {}
}
}
}
(4) 分組查詢
POST goods/_search
{
"aggs": {
"brandNameName": {
"terms": {
"field": "brandName"
}
}
}
}
(5) 子查詢
POST goods/_search
{
"aggs": {
"brandNameName": {
"terms": {
"field": "brandName"
},
"aggs": {
"avgPrice": {
"avg": {
"field": "price"
}
}
}
}
}
}
8.分析分詞
相對一些分析進行分析時,看看ES怎么拆分的,可以用這個查看。
POST _analyze
{
"analyzer": "standard",
"text": "Linus 在90年代開發出了linux操作系統"
}
POST _analyze
{
"analyzer": "ik_max_word",
"text": "Linus 在90年代開發出了linux操作系統"
}
POST _analyze
{
"analyzer": "ik_smart",
"text": "Linus 在90年代開發出了linux操作系統"
}
POST _analyze
{
"analyzer": "ik_smart",
"text": "中華人民共和國國歌"
}
POST _analyze
{
"analyzer": "ik_max_word",
"text": "中華人民共和國國歌"
}
三、總結
本文主要介紹了常見DSL的用法,主要是幫助記憶,避免一些基本的操作還要去查詢文檔的尷尬。記住以下3句話,即可記住DSL的輪廓了:
- 索引、文檔和查詢
- Match、Term和Bool
- 還有翻頁和聚合