文章目录
Elasticsearch学习的第二天
- 全文检索:倒排索引
- Elasticsearch基于lucene实现:
一、ES核心概念
1. Near Realtime(NRT):近实时
从写入数据到数据可以被搜索到有一个小延迟(大概1秒),基于es执行搜索和分析可以达到秒级。
2. Cluster:集群
包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称)来决定,对于中小型应用来说刚开始一个集群就一个节点很正常。
3. Node:节点
集群中的一个节点,节点也有一个名称(默认随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为”elasticsearch“的集群,如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群。
4. Docment:文档
es中的最小数据单元,一个docment可以是一条客户数据,一条商品分类数据,一条订单数据,通常用Json数据结构表示,每个index下的type中,都可以存储多个docment。
5. Index:索引
包含一推有相似结构的文档数据,比如,可以有一个客户索引,商品分类索引,订单索引,索引有一个名称。
6. Type:类型
每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的docment,都有相同的field,比如博客系统,有一个索引,包含用户数据type,博客数据type,评论数据type。
7. shard:分片
单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据让搜索和分析操作分布到多台服务器上去执行,提升吞吐量和性能。每个shard都是一个lucene index。
8. replica:副本
任何一个服务器随时都可能故障和宕机,此时shard可能就会丢失,因此可以为每个shard创建多个replica副本。replica可以在shard故障时提供备用服务,保证数据不丢失,多个replica还可以提升搜索操作的吞吐量和性能。primary shard(建立索引时一次设置,不能修改,默认5个),replica shard(随时修改数量,默认1个),默认每个索引10个shard,其中5个primary shard和5个repl shard,最小的高可用配置是2台服务器。
二、ES的CRUD操作
在kibana里的Dev Tools操作
1、docment数据格式:
- 应用系统的数据结构都是面向对象的,复杂的。
- 对象数据存储到数据库中,只能拆解开来,变为扁平的多张表,每次查询的时候还得还原回对象格式,相对麻烦。
- es是面向文档的,文档中存储的数据结构,与面向对象的数据结构是一致的,基于这种文档数据结构,es可以提供复杂的索引,全文检索,分析聚合等功能。
- es的docment用json数据格式来表达。
2、简单的集群操作:
- 快速检查集群健康状况:
GET /_cat/health?v
// 显示如下:
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1581080440 13:00:40 elasticsearch yellow 1 1 6 6 0 0 6 0 - 50.0%
健康状态?green、yellow、red
- green:每个索引的primary shard和replica shard都是active状态的
- yellow:每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态
- red:不是所有索引的primary shard都是active的,部分索引有数据丢失了
- 快速查看集群中有哪些索引:
GET /_cat/indices?v
// 显示如下:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open bigdata 5PzFnw5mShehmgi7df5JbQ 5 1 2 0 9kb 9kb
yellow open .kibana YIpzq22dTvW_kIs5VgS0yw 1 1 1 0 3.2kb 3.2kb
-
简单的索引操作:
创建索引:PUT /test_index?pretty
删除索引:
DELETE /test_index?pretty
-
docment全局替换:
PUT test/type/1 { "name":xxx, "age":20 }
-
docment强制创建:
PUT test/type/1/_create { "name":xxx, "age":20 }
-
docment的删除:
DELETE test/type/1
3、CURD操作:
-
3.1 新增商品:新增文档,建立索引
语法: PUT index/type/idPUT /ecommerce/product/1 { "name":"高露洁牙膏", "desc":"高效美白", "price":30, "producer":"高露洁厂家", "tags":["美白","防蛀"] } PUT /ecommerce/product/2 { "name":"佳洁士牙膏", "desc":"有效防蛀", "price":25, "producer":"佳洁士厂家", "tags":["防蛀"] } PUT /ecommerce/product/3 { "name":"中华牙膏", "desc":"草本植物", "price":18, "producer":"中华厂家", "tags":["清新","防蛀"] }
es会自动建立index和type,不需要提前建立,而且es默认会对docment每个field都建立倒排索引,让其可以被搜索。
-
3.2 查询商品:检索文档
语法: GET ecommerce/product/1 -
3.3 修改商品:替换文档
PUT /ecommerce/product/3 { "name":"中华牙膏3", "desc":"草本植物3", "price":18, "producer":"中华厂家", "tags":["清新","防蛀"] }
-
3.4 修改商品:更新文档
POST /ecommerce/product/3/_update { "doc":{ "name":"中华牙膏", "desc":"草本植物3", "price":58 } }
-
3.5 删除商品:删除文档
DELETE /ecommerce/product/3?pretty
4、搜索方式:
-
4.1 query string search
搜索全部商品:GET ecommerce/product/_search
搜素全部的商品名称中包含”牙膏“的商品,而且按照售价降序排序:
GET ecommerce/product/_search?q=name:牙膏&sort=price:desc
- 返回值详解:
took:耗时,毫秒
time_out:是否超时
_shards:
hits:查询结果
hits.total:查询结果数量
hits.max_score:docment对于一个search的相关匹配分数
hits.hits:包含了匹配搜索的docment的详细数据 - 适应于临时在命令行使用一些工具,不如curl,快速发出请求,来检索想要的信息,但是如果查询很复杂是很难构建的,在生产环境中,几乎很少很少使用。
- 返回值详解:
-
4.2 query DSL
全称:Domain Specified Language,把查询的语句放到请求体中,使用json的格式来构建查询语法,比较方便,可以构建各种复杂的语法。
搜索全部商品:GET ecommerce/product/_search { "query":{"match_all":{}} }
搜素全部的商品名称中包含”牙膏“的商品,而且按照售价降序排序:
GET ecommerce/product/_search { "query": { "match": { "name": "牙膏" } }, "sort": [ { "price": { "order": "asc" } } ] }
分页查询商品:
从第几个商品开始,查几个,0代表第一个商品GET ecommerce/product/_search { "query": {"match_all": {}}, "from": 1, "size": 2 }
指定显示查询出的商品名称和价格:
GET ecommerce/product/_search { "query": {"match_all": {}}, "_source":["name","price"] }
-
4.3 query filter
对数据进行过滤
搜索商品名称包含”牙膏“,而且售价大于25的:GET ecommerce/product/_search { "query": { "bool": { "must":{ "match":{ "name":"牙膏" } }, "filter": { "range": { "price": { "gt": 2 } } } } } }
-
4.4 全文检索
GET ecommerce/product/_search { "query": { "match": { "producer": "牙膏厂家" } } }
-
4.5 短语搜索(phrase search)
跟全文检索相对反,全文检索会将输入的搜索串拆解开来,去倒排索引里面去一一匹配,只有能匹配上任意一个拆解后的单词,就可以作为结果返回,而phrase search,要求输入的搜索串,必须在指定的字段文本中,完全包含一模一样的才可以算匹配,才能返回结果。GET ecommerce/product/_search { "query": { "match_phrase": { "producer": "牙膏厂家" } } }
-
4.6 高亮搜索结果(phrase search)
GET ecommerce/product/_search { "query": { "match": { "name": "牙膏" } }, "highlight": { "fields": { "name": {} } } }
5、聚合查询:
设置tags的fielddata属性true
PUT ecommerce/_mapping/product
{
"properties": {
"tags":{
"type": "text",
"fielddata": true
}
}
}
-
计算每个tags下的商品数量,分组聚合
GET ecommerce/product/_search { "size": 0, // 显示原始几条数据 "aggs": { "group_by_tags": { // 自定义名称 "terms": { "field": "tags", "size": 10 } } } }
-
对包含”牙膏“的商品,计算每个tags下的商品数量,先搜索再分组聚合
GET ecommerce/product/_search { "query": { "match": { "name": "牙膏" } }, "size": 0, "aggs": { "group_by_tags": { "terms": { "field": "tags", "size": 10 } } } }
-
计算每个tags下的商品数量,并计算它们的平均价格,分组聚合后再聚合
GET ecommerce/product/_search { "size": 0, "aggs": { "groug_by_tags": { "terms": { "field": "tags" }, "aggs": { "avg_price": { "avg": { "field": "price" } } } } } }
-
计算每个tags下的商品平均价格,并且按照平均价格降序排序
GET ecommerce/product/_search { "size": 0, "aggs": { "groug_by_tags": { "terms": { "field": "tags", "order": {"avg_price": "desc" } }, "aggs": { "avg_price": { "avg": { "field": "price" } } } } } }
-
按照指定的价格区间进行分组,然后在每组内再按照tag进行分组,最后再计算每组的平均价格
GET ecommerce/product/_search { "size": 0, "aggs": { // 聚合函数 "group_by_price": { // 自定义函数名 "range": { // 使用范围函数 "field": "price", // 使用函数的字段 "ranges": [ // 范围 { "from": 0, "to": 24 }, { "from": 25, "to": 50 } ] }, "aggs": { // 嵌套聚合函数 "group_by_tags": { // 自定义函数名 "terms": { // 分组函数 "field": "tags" // 使用函数的字段 }, "aggs": { // 嵌套聚合函数 "avg_price": { // 自定义函数名 "avg": { // 平均函数 "field": "price" // 使用函数的字段 } } } } } } } }