ElasticSearch7查询、删除、更新常用API

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"
      ]
    }
  }
}

一定要了解 termterms包含(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条数据开始(不包括第五条),取两条:即取第67两条数据
{
  "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_nodesnumber_of_data_nodes :节点数
  • active_primary_shards :集群中主分片数量,所有索引的汇总值
  • active_shards :所有索引的所有分片的汇总,包括副本分片
  • relocating_shards :显示当前正在从一个节点迁往其他节点的分片的数。通常为 0,ES 发现集群不太均衡时,该值会上涨。如:添加或下线了一个新节点
  • initializing_shards :刚刚创建的分片的个数。如刚创建第一个索引,分片都会短暂的处于 initializing 状态
  • unassigned_shards :已经在集群状态中存在的分片,但是实际在集群里又找不到。通常未分配分片的来源是未分配的副本以及它的全部副本)缺失。这意味着在丢失数据:搜索只能返回部分数据,而分配到这个分片上的写入请求会返回异常
集群统计
GET _cluster/stats

# 集群的详细信息统计:集群数、状态、版本、操作系统、进程、jvm、内存、ES插件、网络等
索引信息
# 索引信息
GET my01.account/_stats

# 索引的mapping信息
GET my01.account/_mapping
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值