文章目錄
-
- ES基礎查詢
-
- 布爾過濾器
- 值比對
- 範圍查詢
- 存在查詢
- 分頁
- 聚合
-
- 桶聚合
- 桶的嵌套
- 去重統計
- 更新資料
-
- ById 更新
- 查詢更新
- 插入更新
- 删除資料
-
- ById删除
- 查詢删除
- 删除索引
- 其他
-
-
- 叢集健康
- 叢集統計
- 索引資訊
-
ES基礎查詢
*ES查詢非常豐富,還有如查詢性能調優、為查詢配置權重、聚合中多桶排序、過濾聚合…以下僅為部分DSL入門文法 本文基于elasticsearch7.x版本
布爾過濾器
包含三種邏輯運算:與或非
{
"bool" : {
"must" : [{},{}...],
"should" : [{},{}...],
"must_not" : [{},{}...],
}
}
執行個體:
{
"query": {
"bool": {
"must": [
{"term": {"color": {"value": "red"}}},
{"term": {"name": {"value": "A"}}}
]
}
}
}
should條件後若要指定比對條件:如最少滿足should中一個條件,需加上minimum_should_match字段:
{
"query": {
"bool": {
"must": [{"term": {"name": {"value": "Tom"}}}],
"should": [
{"term": {"color": {"value": "red"}}},
{"term": {"name": {"value": "A"}}}
],
"minimum_should_match": 1
}
}
}
值比對
term:字段精确比對單個值
terms:字段比對多個精确值
# "FIELD"字段值精确比對"VALUE1"或"VALUE2"
{
"query": {
"terms": {
"FIELD": [
"VALUE1",
"VALUE2"
]
}
}
}
一定要了解和
term
terms
是 包含(contains) 操作,而非 等值(equals) 判斷。 如何了解?
如果我們有一個 term過濾器
,它會與以下兩個文檔 同時比對:
{ "term" : { "tags" : "search" } }
{ "tags" : ["search"] } { "tags" : ["search", "open_source"] }
match:模糊比對:和平常了解的字元串模糊比對有差別,match比對依賴分詞
wildcard:模糊比對:字元串模糊比對
{
"query": {
"wildcard": {
"postcode": "W?F*HW"
}
}
}
# ? 比對單字元 * 比對任意字元
match_phrase:模糊短語比對,不用分詞模式。即如“ A B”,是位置敏感比對,會去比對A在B前的内容
multi_match:多字段模糊比對單個值
# 傳回"model"和"name"兩個字段中包含"test"的文檔
{
"query": {
"multi_match": {
"query": "test",
"fields": ["name","color"]
}
}
}
match_phrase_prefix:比對字段值以**開頭
regexp:正則比對
範圍查詢
range:範圍查詢
# 查詢"age"大于等于10,小于等于20
{
"query": {
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
}
當然,也可以判斷日期類型資料,加上format指定日期格式即可
{
"query": {
"range": {
"datatime": {
"gte": "2020-05-11:12:00:00",
"lte": "2021-06-11:24:00:00",
"format": "yyyy-MM-dd:HH:mm:ss"
}
}
}
}
# 當使用它處理日期字段時,range查詢支援對日期計算操作,如我們想查找時間戳在過去一小時内的所有文檔:
{
"range" : {
"timestamp" : {
"gt" : "now-1h"
}
}
# 更多日期格式參考文檔:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/mapping-date-format.html
範圍表達式
:
gt
大于
>
:
lt
小于
<
:
gte
大于或等于
>=
:
lte
小于或等于
<=
存在查詢
對應sql中的null判斷:
SELECT *
FROM table
WHERE `name` IS NULL
exists:必須存在值
必須不存在值可用must_not實作:
GET cars/_search
{
"query": {
"bool": {
"must_not": [
{"exists": {"field": "color"}}
]
}
}
}
分頁
對應sql中的 limit 5,2
from – size
# 從第5條資料開始(不包括第五條),取兩條:即取第6、7兩條資料
{
"query": {},
"from": 5,
"size": 2
}
聚合
桶聚合
桶 簡單說即滿足特定條件的文檔的集合(類似mysql中的分組):
- 一個人屬于 男性 桶或者 女性 桶
- 張三屬于 四川桶
- 日期2014-10-28屬于 十月 桶
當聚合開始被執行,每個文檔裡面的值通過計算來決定符合哪個桶的條件。比對到,文檔将放入相應的桶并接着進行下一個聚合操作
桶也可以嵌套在其他桶裡面,提供階層化或有條件的劃分方案。如,張三被放入四川這個桶,而整個四川桶會被放入中國這個桶
Elasticsearch 有很多種類型的桶,能讓你通過很多種方式來劃分文檔(時間、熱詞、年齡區間、地區等)。其實根本上都是通過同樣的原理進行操作:基于條件來劃分文檔
桶聚合的兩個重要概念:
桶(Buckets)
滿足特定條件的文檔的集合
名額(Metrics)
對桶内的文檔進行統計計算
類比sql中的分組:
SELECT COUNT(name)
FROM table
GROUP BY `name`
COUNT(name)
相當于名額;
GROUP BY name
相當于桶
桶在概念上類似于 SQL 的分組(GROUP BY),而名額則類似于
COUNT()
、
SUM()
、
MAX()
等統計方法
簡單執行個體:
# 在言論表中,對言論通過人員id-uid聚合(分組)
{
"size": 0,
"aggs": {
"NAME0": {
"terms": {
"field": "uid",
"size": 2
}
}
}
}
# aggs:聚合操作頂層參數 NAME0:自定義的桶名 terms:桶類型
響應:
"aggregations" : {
"NAME0" : {
"doc_count_error_upper_bound" : 2985,
"sum_other_doc_count" : 398001,
"buckets" : [
{
"key" : "211074217e7f621c4ccd46a949140332",
"doc_count" : 7333
},
{
"key" : "8780646c1e6fecd11270ef816e9bf80b",
"doc_count" : 7207
}
]
}
}
類比sql,其對應語句應為:
SELECT *
FROM `my01.dynamic`
GROUP BY `uid`
LIMIT 2
桶的嵌套
同樣地,如果我們想對聚合後的桶(各個分組)進行一些分析計算,就可以使用嵌套桶,了解這個概念,可以類比sql中的having
執行個體:一張言論表中将言論通過uid分組後,統計各個桶中言論的點贊平均數:
{
"size": 0,
"aggs": {
"NAME0": {
"terms": {
"field": "uid",
"size": 2
},
"aggs": {
"NAME1": {
"avg": {
"field": "likeCount"
}
}
}
}
}
}
響應:
"aggregations" : {
"NAME0" : {
"doc_count_error_upper_bound" : 2985,
"sum_other_doc_count" : 398001,
"buckets" : [
{
"key" : "211074217e7f621c4ccd46a949140332",
"doc_count" : 7333,
"NAME1" : {
"value" : 694.6413473339697
}
},
{
"key" : "8780646c1e6fecd11270ef816e9bf80b",
"doc_count" : 7207,
"NAME1" : {
"value" : 613.4125156098238
}
}
]
}
}
類比sql中的having,統計聚合後組中點贊數大于20的言論:
SELECT *
FROM `my01.dynamic`
GROUP BY `uid`
HAVING `likeCount`>20
LIMIT 2
去重統計
cardinality:聚合去重統計字段
執行個體:言論表中将言論通過uid分組後,去重統計每個桶的言論釋出類型
{
"size": 0,
"aggs": {
"NAME0": {
"terms": {
"field": "uid",
"size": 2
},
"aggs": {
"NAME1": {
"cardinality": {
"field": "postType"
}
}
}
}
}
}
響應:
"aggregations" : {
"NAME0" : {
"doc_count_error_upper_bound" : 2985,
"sum_other_doc_count" : 398733,
"buckets" : [
{
"key" : "211074217e7f621c4ccd46a949140332",
"doc_count" : 7333,
"NAME1" : {
"value" : 2
}
},
{
"key" : "8780646c1e6fecd11270ef816e9bf80b",
"doc_count" : 7207,
"NAME1" : {
"value" : 2
}
}
]
}
}
當然,也可以用于不分組的全量字段的去重統計:
{
"size": 0,
"aggs": {
"NAME": {
"cardinality": {
"field": "postType"
}
}
}
}
類比sql中的 distinct:
SELECT DISTINCT("postType")
FROM `my01.dynamic`
更新資料
ById 更新
update:通過id更新單條資料
POST my01.dynamic-000001/_update/231d2140e8649f6d30b50b3a01b07adc
{
"doc":{
"type":"評論",
"aId" : "2d277ab04ca11d52d26ed62b10df07f8"
}
}
# 格式:
POIST {index}/_update/{id}
{
"doc":{"KEY1":"VALUE1"...}
}
查詢更新
_update_by_query:通過查詢條件更新。用法相對複雜,單獨寫一篇介紹
插入更新
除了_update API可以更新文檔,還可以通過插入資料的方式更新文檔
執行個體:
# 往索引"info.feature_tag"插入id為"test172848575238167ujry8"的資料,如果該id存在,則修改該id下的資料為目前插入值
POST info.feature_tag/_doc/test172848575238167ujry8
{
"id": "test172848575238167ujr88test",
"status": "active",
"indexId": 564565,
"XxId": "test826c7aa544754aeeb2646c26814a7a78",
"Name": "名字test",
"subjectName": "項目名字test",
"province": "廣東省",
"city": "深圳市",
"area": "無",
"industry": "消費",
"riskScore": 85,
"riskLevel": 2,
"values": "test"
"eventTime": "2021-06-01",
"gmtCreate": "2020-03-19 06:31:21",
"tagType": "company",
}
# 格式:
POIST {index}/_doc/{id}
{
···
}
删除資料
ById删除
用于通過文檔id删除單條資料
# 删除cars索引下id=1的資料
DELETE cars/_doc/1
查詢删除
删除符合查詢條件的所有資料
# 删除cars索引下"color"為"white"的所有文檔
POST cars/_delete_by_query
{
"query": {
"term": {
"color": {
"value": "white"
}
}
}
}
删除索引
删除整個索引,類比删除mysql中的資料庫
# 删除cars索引
DELETE cars
# 響應:
{
"acknowledged" : true
}
有時因資料量較大删除到一半就傳回結果了,再多執行幾次就ok
其他
叢集健康
GET _cluster/health
響應:
{
"cluster_name" : "elasticsearch-7-6",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 4,
"number_of_data_nodes" : 4,
"active_primary_shards" : 376,
"active_shards" : 800,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
響應中最重要的字段status,狀态可能是下列三個值之一:
–
green
:所有的主分片和副本分片都已配置設定。叢集是 100% 可用的
–
yellow
:所有的主分片已經分片了,但至少還有一個副本是缺失的。不會有資料丢失,是以搜尋結果依然是完整的
–
:至少一個主分片(以及它的全部副本)缺失。這意味着在丢失資料:搜尋隻能傳回部分資料,而配置設定到這個分片上的寫入請求會傳回異常
red
和
number_of_nodes
:節點數
number_of_data_nodes
:叢集中主分片數量,所有索引的彙總值
active_primary_shards
:所有索引的所有分片的彙總,包括副本分片
active_shards
:顯示目前正在從一個節點遷往其他節點的分片的數。通常為 0,ES 發現叢集不太均衡時,該值會上漲。如:添加或下線了一個新節點
relocating_shards
:剛剛建立的分片的個數。如剛建立第一個索引,分片都會短暫的處于 initializing 狀态
initializing_shards
:已經在叢集狀态中存在的分片,但是實際在叢集裡又找不到。通常未配置設定分片的來源是未配置設定的副本以及它的全部副本)缺失。這意味着在丢失資料:搜尋隻能傳回部分資料,而配置設定到這個分片上的寫入請求會傳回異常
unassigned_shards
叢集統計
GET _cluster/stats
# 叢集的詳細資訊統計:叢集數、狀态、版本、作業系統、程序、jvm、記憶體、ES插件、網絡等
索引資訊
# 索引資訊
GET my01.account/_stats
# 索引的mapping資訊
GET my01.account/_mapping