什么是es?
Elasticsearch 是由Apache开源的一个兼有搜索引擎和NoSQL数据库功能的系统,其特点主要如下。
基于Java/Lucene构建,支持全文搜索、结构化搜。
低延迟,支持实时搜索
分布式部署,可横向集群扩展
支持百万级数据
支持多条件复杂查询,如聚合查询
高可用性,数据可以进行切片备份
支持Restful风格的api调用
概述
Elasticsearch是面向文档(document)的,这意味着它可以存储整个对象或文档。会索引每个文档的内容使之可以被搜索。在Elasticsearch中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。Elasticsearch比传统关系型数据库如下:
Relational DB ‐> Databases ‐> Tables ‐> Rows ‐> Columns
Elasticsearch ‐> Indices ‐> Types ‐> Documents ‐> Fields
ES应用场景
ES作为全文检索的搜索引擎,在以下几个方面都存在着相应的应用:
监控。针对日志类数据进行存储、分析、可视化。针对日志数据,ES给出了ELK的解决方案。其中logstash采集日志,ES进行复杂的数据分析,kibana进行可视化展示。
电商网站。用于商品信息检索。
Json文档数据库。用于存放json格式的文档
*。提供全文搜索并高亮关键字
应用在大数据层面较多,与logstach和kibana组成一整套的采集,搜索,分析和可视化
我们系统目前应用到的有:慢病、标准药品数据。特点就是数据量大,速度快
核心概念
1)index索引
一个索引就是一个拥有几分相似特征的文档的集合。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。类比mysql中的数据库
2)type类型
在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类。通常,会为具有一组共同字段的文档定义一个类型。 可类比mysql中的表。
注:es7已废弃。因为在关系型数据库中table是独立的(独立存储),但es中同一个index中不同type是存储在同一个索引文件中的,因此不同type中相同名字的字段的定义(类型)必须一致。替换策略为一个index索引存储一种类型的记录
3)document文档
一个文档是一个可被索引的基础信息单元。文档以JSON格式来表示。在一个index/type里面,你可以存储任意多的文档。类比与数据库中的一行数据
4) Filed字段
相当于是数据表的字段,对文档数据根据不同属性进行的分类标识 。
5)映射mapping
mapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其它处理es数据的一些使用规则设置也叫做映射。相当于mysql中的创建表的过程,设置主键外键字段类型等
6)集群cluster
7)节点node(主节点,数据节点,协调节点)
8)分片和复制 shards&replicas
实操
集群&索引操作
查看集群健康状况
GET /_cat/health?v&pretty
查看指定索引(my_index)的mapping和setting的相关信息
GET /my_index?pretty
查看所有的index
GET /_cat/indices?v&pretty
创建一个分片数3,没有复制分片名为my_index的索引
PUT my_index { "settings": { "number_of_shards": 1, "number_of_replicas": 0 }, "mappings": { "properties": { "name": { "type": "text" }, "age": { "type": "integer" }, "mobile": { "type": "keyword" }, "context": { "type": "text" } } } }
修改索引的设置
PUT /my_index/_settings { "number_of_replicas": 1 }
(6)删除索引
DELETE /my_index
(7)删除多个索引
DELETE /index_one,index_two
DELETE /index_*
DELETE /_all
字段类型
text
当一个字段的内容需要被全文检索时,可以使用text类型,支持长内容的存储,比如检索文章内容、商品信息等。该类型的字段内容在保存时会被分词器分析,并且拆分成多个词项。text类型的字段无法通过指定文本精确的检索到,同时不能用于过滤、排序、聚合操作
keyword
keyword不会被分词器分析,适合做精确查询。比如手机号,身份证号,用户id等。可用于过滤、排序、聚合操作。
3)日期类型date
类型默认支持如下两种格式:
strict_date_optional_time
表示 yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ 或者 yyyy-MM-dd 格式的日期
epoch_millis
表示从 1970.1.1 零点到现在的毫秒数,如果我们要存储类似
这种格式的日期就会有问题,我们可以在创建索引时指定字段为date类型以及可以匹配的日期格式:
PUT blog { "mappings": { "properties": { "createDate":{ "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } }
4) 布尔类型
boolean,有true和false两个值
5) 数值类型
short、 integer、long、double、float
6)数组类型
es中没有数组类型,它的字段默认可以存储一个或多个值。
文档操作
创建文档
POST /my_index/_doc/f2daf45df25sa5fd4d58 { "name":"李强", "age":28 }
注:id可加可不加,不加的话es自动生成该文档的id
修改文档
两种写法
POST /my_index/_doc/f2daf45df25sa5fd4d58 { "name":"李强", "age":21 }
POST /my_index/_update/f2daf45df25sa5fd4d58 { "doc":{ "name":"李强", "age":28 } }
注:id必填。第二种_update请求体中需要将字段包type类型(doc)中。type类型名字可以在创建索引时指定,默认_doc。es7版本虽然已废弃,但还在使用
删除文档
DELETE /my_index/_doc/{id}
查询文档
match query
match query 用于搜索单个字段,首先会针对查询语句进行解析,主要是对查询语句进行分词,分词后查询语句的任何一个词项被匹配,文档就会被搜到,默认情况下相当于对分词后词项进行 or 匹配操作。
GET ip:/my_index/_search { "query": { "match": { "name": { "query": "" } } } }
如果想查询匹配到全部关键词的文档,可以用 and 操作符连接,如下:
GET my_index/_search { "query": { "match": { "name": { "query": "", "operator": "and" } } } }
multi_match
multi_match 是 match 的升级,用于搜索多个字段。查询语句为“”。field可以定义字段及权重
GET my_index/_search { "query": { "multi_match": { "query": "", "fields": ["context^3", "name"] } } }
term query
term 查询用来查找指定字段中包含给定单词的文档,term 查询不被解析,只有查询词和文档中的词精确匹配才会被搜索到
GET my_index/_search { "query": { "term": { "mobile": “" } } }
terms query
terms 查询是 term 查询的升级,可以用来查询文档中包含多个词的文档。相当于sql中的in
{ "query": { "terms": { "mobile": ["", ""] } } }
range query
即范围查询,用于匹配在某一范围内的数值型、日期类型或者字符串型字段的文档
range 查询支持的参数有以下几种:
gt 大于,查询范围的最小值,也就是下界,但是不包含临界值。
gte 大于等于,和 gt 的区别在于包含临界值。
lt 小于,查询范围的最大值,也就是上界,但是不包含临界值。
lte 小于等于,和 lt 的区别在于包含临界值。
例如:查询年龄23到25
GET bookes/_search { "query": { "range": { "age": { "gt": 23, "lte": 25 } } } }
bool query
bool 查询可以把任意多个简单查询组合在一起,使用 must、should、must_not、filter 选项来表示简单查询之间的逻辑,它们的含义如下:
must 文档必须匹配 must 选项下的查询条件,相当于逻辑运算的 AND,且参与文档相关度的评分。
should 文档可以匹配 should 选项下的查询条件也可以不匹配,相当于逻辑运算的 OR,且参与文档相关度的评分。
must_not 与 must 相反,匹配该选项下的查询条件的文档不会被返回;需要注意的是,must_not 语句不会影响评分,它的作用只是将不相关的文档排除。
filter 和 must 一样,匹配 filter 选项下的查询条件的文档才会被返回,但是 filter 不评分,只起到过滤功能
例子:查询名字中包含”强“。且年龄不大于25
GET my_index/_search { "query": {
"bool": { "must_not": { "range": { "age": { "lte": 25 } } }, "must": { "match": { "name": "强" } } } } }
聚合查询
terms agges 类似于group by
例:查询数据中每个年龄的值及每个年龄数量
GET my_index/_search { "size": 0, "aggs": { "job_info": { "terms": { "field": "job" } } } }
其他还有cardinality聚合、date_histogram 聚合、Pipeline 聚合查询等,时间原因不做过多描述,感兴趣可以自行百度。
作者:joshua317