一、简述
随着互联网技术的不断发展,技术的不断迭代更新,会有很多新的产品涌现出来,我们也需要不断地学习来掌握这些产品。
不知道大家接触到的项目是否已经使用Elasticsearch了,但在平时了解一些技术架构肯定会听到「搜索使用es」、「日志都通过消息中间件放到es里面了」……
这个时候,如果对Elasticsearch不了解的同学,可能心里会一慌,这个es,我还不懂啊……
所以说这篇文章就是Elasticsearch的基本介绍、最常用的知识点。希望看完后能对你有所帮助。
二、主要内容
Elasticsearch简介、核心概念; Elasticsearch中对索引、文档的常用操作方法; Elasticsearch中常见元数据介绍; Elasticsearch中的搜索语言:DSL--Domain Specific Language
三、Elasticsearch简介
Elasticsearch是什么?
Elasticsearch 是一个基于JSON的分布式搜索和分析引擎,基于restful web接口。Elasticsearch是用Java语言开发的,基于Apache协议的开源项目,是目前最受欢迎的企业搜索引擎。
ELK是什么?
“ELK”是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。Elasticsearch 是一个搜索和分析引擎。Logstash 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库”中。Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。
Elasticsearch核心概念
Cluster-集群
Elasticsearch集群由一或多个节点组成,其中有一个主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。
Elasticsearch的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部看Elasticsearch集群,在逻辑上是个整体,你与集群中的任何一个节点通信和与整个Elasticsearch集群通信是等价的。
Shards-分片
当索引存储大量数据时,可能会超出单个节点的硬件限制,为了解决这个问题,Elasticsearch提供了将索引细分为分片的概念。分片又分为:主分片和副本分片。
primary shard:代表索引的主分片,一个索引可以分成多个主分片。
replica shard:代表索引主分片的副本。
Index-索引
类似于mysql数据库中的表。其中存储若干相似结构的Document数据。如:客户索引,订单索引,商品索引等。
Type-类型
可以理解为表逻辑类型,es中可以在Index中建立type。
注意:Elasticsearch5.x及更低版本中,一个Index中可以有多个Type。Elasticsearch6.x版本之后,type概念被弱化,一个index中只能有唯一的一个type。且在7.x版本之后,删除type定义。
Document
Elasticsearch中的最小数据单元。一个Document就是一条数据,一般使用JSON数据结构表示。
Field
es中一个文档中对应的多个列与mysql数据库中每一列对应
Query DSL
类似于mysql的sql语句,只不过在es中是使用的json格式的查询语句,专业术语就叫:QueryDSL
GET/PUT/POST/DELETE
分别类似与mysql中的select/update/delete......可以直接通过RESTFUL的方式进行调用
四、Elasticsearch常用操作
集群状态相关操作
查看集群健康状态
GET /_cat/health?v
集群状态 解释:status:green、yellow、red
green:每个索引的primary shard和replica shard都是active的
yellow:每个索引的primary shard都是active的,但部分的replica shard不是active的
red:不是所有的索引的primary shard都是active状态的。
查看节点健康状态
GET /_cat/nodes?v
节点健康状态 查看所有索引信息
GET /_cat/indices?v
索引信息 查看分片信息
GET _cat/shards?v
分片信息
索引相关操作
创建索引
命令语法:PUT 索引名{索引配置参数}
索引名称必须是小写的,且不能以下划线'_','-','+'开头。
示例:
PUT test_index
修改索引
命令语法:PUT 索引名/_settings{索引配置参数}
索引一旦创建,primary shard数量不可变化,可以改变replica shard数量。
示例:
PUT test_index/_settings
{
"number_of_replicas" : 2
}
删除索引
命令语法:DELETE 索引名1[, 索引名2 ...]
示例:
DELETE test_index
文档相关操作
新增文档
在索引中增加文档。Elasticsearch有自动识别机制。如果增加的document对应的index不存在,自动创建index;如果index存在,type不存在,则自动创建type。如果index和type都存在,则使用现有的index和type。
PUT 语法
可以自行指定文档ID
命令语法:PUT 索引名/类型名/唯一ID{字段名:字段值}
示例:
PUT test_index/test_type/1
{
"name":"test_put",
"remark":"test",
"order_no":1
}补充语法:PUT 索引名/类型名/唯一ID/「_create」{字段名:字段值}
_create:强制新增。使用强制新增语法时,如果Document的id在Elasticsearch中已存在,则会报错。(version conflict, document already exists)
POST语法
Elasticsearch自动生成id
命令语法:POST 索引名/类型名{字段名:字段值}
示例:
POST test_index/test_type
{
"name":"tes_post",
"remark":"test",
"order_no":4
}
查询文档
通过ID查询单条数据
命令语法:GET 索引名/类型名/唯一ID
示例:
GET test_index/test_type/1批量查询
可以借助于元数据「_mget」,这个方式就比较多了。
示例:
# 第一种
GET _mget
{
"docs" : [
{
"_index" : "索引名",
"_type" : "类型名",
"_id" : "唯一ID值"
}, {}, {}
]
}
# 第二种
GET 索引名/_mget
{
"docs" : [
{
"_type" : "类型名",
"_id" : "唯一ID值"
}, {}, {}
]
}
# 第三种
GET 索引名/类型名/_mget
{
"docs" : [
{
"_id" : "唯一ID值"
},
{
"_id" : "唯一ID值"
}
]
}
更新文档
在Elasticsearch里面更新的操作,其不会真的修改Document中的数据,而是标记Elasticsearch中原有的Document为deleted状态,再创建一个新的Document来存储数据。更新有两种方式:
全量更新
命令语法:PUT 索引名/类型名/唯一ID{字段名:字段值} 与新增的put语法是一样的。
部分更新
命令语法:POST 索引名/类型名/唯一ID/_update{doc:{字段名:字段值}}
示例:
POST test_index/test_type/1/_update
{
"doc":{
"name":" test_post_for_update"
}
}
删除文档
Elasticsearch中执行删除操作时,Elasticsearch先标记Document为deleted状态,而不是直接物理删除。当Elasticsearch存储空间不足或工作空闲时,才会执行物理删除操作。标记为deleted状态的数据不会被查询搜索到。
命令语法:DELETE 索引名/类型名/唯一ID
示例:
DELETE test_index/test_type/1
文档乐观锁
在较老的版本里面Es对每一条数据都提供了一个版本元数据:
_version
:文档版本号,记录数据变更的次数。
在较新的版本里面有两个新的版本元数据:
_seq_no
:文档版本号,作用同_version
。
_primary_term
:文档所在位置。
使用示例:
# 更新文档数据的时候,加上乐观锁,确保数据不会被覆盖掉。
POST /myindex/_doc/{id}/_update?if_seq_no={数值}&if_promary_term={数值}
{
"name":"xxx"
}
主要数据类型
text、keyword long、integer、short、byte double、float boolean date object
五、常用元数据介绍
元数据通常使用下划线’_’开头。在使用查询文档时,返回结果中不仅包括我们存入的数据,还包括各元数据。
_index
代表的是文档数据存入的索引名称。
_type
代表的是文档数据存入的是索引中的类别。
_id
代表文档的唯一标识。使用index、type和id可以定位唯一的一个文档。
_source
代表的是文档的JSON串信息。
_version
代表的是文档的版本。每次数据变化,版本都会发生变更。
_score
查询相关度,是否契合用户匹配,分数越高用户的搜索体验越好。
六、数据搜索(DSL)
Elasticsearch 提供了一个基于 JSON 的完整查询语法:DSL--Domain Specific Language,查询参数是一段JSON。
语法格式:
POST 索引名/_search
{
"command":{ "parameter_name" : "parameter_value"}
}
查询所有数据-match_all
查询索引中的所有文档可以使用 match_all ,可以使用_source来指定想要展示的字段
POST 索引名/类型名/_search
{
"query":{
"match_all":{}
},
"_source":{
"字段1","字段2","字段3"
}
}
分页查询-from size
默认查询是10条数据
POST 索引名/类型名/_search
{
"query":{
"match_all":{}
},
"from":0,
"size":10
}
匹配查询-match query
搜索条件在进行拆词之后的词条与任意可以匹配上的数据就是搜索结果。
match有一个配置项:operator,它有两个值:or和and.
or:搜索条件拆词之后,只要有一个词条匹配就展示结果,默认都是这样的。 and:搜索条件拆词之后,都要满足词语匹配才可以。
POST 索引名/类型名/_search
{
"query": {
"match": {
"字段名": "搜索条件"
}
}
}
# 等价于
POST 索引名/类型名/_search
{
"query": {
"match": {
"字段名": "搜索条件",
"operator": "or"
}
}
}
根据文档主键查询-ids query
# 单条
GET 索引名/类型名/id
# 多条
POST 索引名/类型名/_search
{
"query":{
"ids":{
"type":"_doc",
"values":["id1","id2","id3"]
}
}
}
多个字段查询-multi_match query
实现同一个搜索条件在多个字段中进行查询的场景。
POST 索引名/类型名/_search
{
"query": {
"multi_match": {
"query": "搜索条件",
"fields":["字段1","字段2","字段3"]
}
}
}
短语查询-match_phrase query
使用match_phrase关键字时,查询条件会被拆词,但是目标数据中必须包含所有词条,而且顺序必须相同,而且必须都是连续的才是结果。
slop:由于match_phrase默认要求词条必须连续才可以,所以这个属性可以配置两个词条之间可以跳过多少个词。
# 语法
POST 索引名/类型名/_search
{
"query": {
"match_phrase": {
"字段名": "搜索条件"
}
}
}
# 示例
POST /myindex/_doc/_search
{
"query": {
"match_phrase": {
"description": {
"query": "手机 老人 大屏",
"slop": 3
}
}
}
}
不分词短语查询-term query
使用term关键字时,查询条件不会被分词,直接拿去匹配目标数据。
# 单个条件
POST 索引名/类型名/_search
{
"query" : {
"term" : {
"字段名": "搜索条件"
}
}
}
# 多个条件
POST 索引名/类型名/_search
{
"query" : {
"terms" : {
"字段名": ["搜索条件1", "搜索条件2"]
}
}
}
范围查询-range query
范围搜索,类似于mysql里面的between…and…
gte
:大于等于 gt
:大于 lte
:小于等于 lt
:小于
POST 索引名/类型名/_search
{
"query" : {
"range" : {
"字段名" : {
"gt" : 搜索条件1,
"lte" : 搜索条件2
}
}
}
}
多条件复合查询-bool
多个条件的查询,使用bool
来进行组合,在bool
里面有几个类型:
must
:表示多个条件必须同时满足;must_not
:表示多个条件必须都不满足;should
:表示多个条件满足其中一个即可;
POST 索引名/类型名/_search
{
"query": {
"bool": {
"must": [ #数组中的多个条件必须同时满足
{
"range": {
"字段名": {
"lt": 条件
}
}
}
],
"must_not":[ #数组中的多个条件必须都不满足
{
"match": {
"字段名": "条件"
}
},
{
"range": {
"字段名": {
"gte": "搜索条件"
}
}
}
]
"should": [# 数组中的多个条件有任意一个满足即可。
{
"match": {
"字段名": "条件"
}
},
{
"range": {
"字段名": {
"gte": "搜索条件"
}
}
}
]
}
}
}
排序-sort
在Elasticsearch的搜索中,默认是使用相关度分数实现排序的。可以通过搜索语法实现定制化排序 。
GET 索引名/类型名/_search
{
"query": {
[搜索条件]
},
"sort": [
{
"字段名1": "asc"
},
{
"字段名2": "desc"
}
]
}
高亮查询-highlight query
在搜索中,经常需要对搜索关键字做高亮显示,这个时候就可以使用highlight语法.
POST 索引名/类型名/_search
{
"query": {
"match": {
"字段名": "条件"
}
},
"highlight": {
"fields": {
"要高亮显示的字段名": {
"fragment_size": 5, #每个分段长度,默认20
"number_of_fragments": 1 #返回多少个分段,默认3
}
},
"pre_tags": ["前缀"],
"post_tags": ["后缀"]
}
}
# 示例
POST myindex/_doc/_search
{
"query":{
"match":{
"description":"手机"
}
},
"highlight":{
"fields": {
"description"{}
},
"pre_tags": ["<span>"],
"post_tags": ["</span>"]
}
}
聚合查询-aggs query
es也提供了丰富的聚合查询,类似于MySQL里面的分组、统计等。具体可以查看官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-aggregations.html
七、总结
如果能耐心看到这里的小伙伴,相信对Elasticsearch已经有了初步的了解。对于日常使用来讲,这些完全够了,Elasticsearch还有一些高深的玩法,后续有机会在总结一下。再有不明白的地方也可以自行查询官网或者私信我一起探讨。
有意思的内容,关注下方公众号,快速获取更多内容,等你来~
点赞、在看、收藏三连击一下,然后再分享给需要的小伙伴!




