1.1. 初识elasticsearch(简称es)
elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容,底层基于基于Lucene实现。下载地址:Download Elasticsearch | Elastic
elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域。
elasticsearch是elastic stack的核心,负责存储、搜索、分析数据。
1.2.正向索引与倒排索引
传统数据库(MySQL)采取正向索引。
es采用倒排索引。
假设向MySQL与es中插入数据,数据(使用id标识),内容(使用value标识),数据中的同一个词汇可能出现多次。
正向索引:从数据角度看,记录每个单词出现的次数,位置。(依据id去寻找value)
倒排索引:从词汇角度看,记录每个词汇分别在哪些数据出现,次数及位置。(按照value出现的次数,位置去寻找对应id)
倒排索引包含两部分内容:
- 词条字典:记录所有词条,词条与倒排列表之间的关系,会给词条创建索引,增加查询与插入效率。
- 倒排列表:记录词条所在的文章的id,词条出现的频率及出现位置信息
文章id:用于快速获取文章
词条频率:文章中词条出现的次数,用于打分。
1.3.对比及关系
MySQL | Elasticsearch | 说明 |
Table | Index | 索引(index),就是文档的集合,类似数据库的表(table) |
Row | Document | 文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式 |
Column | Field | 字段(Field),就是JSON文档中的字段,类似数据库中的列(Column) |
Schema | Mapping | Mapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema) |
SQL | DSL | DSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD |
MySQL:负责事务类型操作及数据的存储。
es:负责海量数据的搜索、分析与计算。
2.1.分析器
es在创建倒排索引前需要对数据进行分词并分别创建索引
列:hello:h e l l o hello
3.1.索引库操作
mapping是对索引库中文档的约束,常见的mapping属性包括:
3.2.查看、删除、修改索引库
查看:GET/索引库名
删除:DELETE/索引库名
修改:索引库与mapping一旦创建就不能更改,但是可以添加新字段
PUT /索引库名/_mapping
{
"properties": {
"新字段名":{
"type": "integer"
}
}
}
3.3.添加、查看、删除、修改文档
POST /索引库名/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
"字段3": {
"子属性1": "值3",
"子属性2": "值4"
},
// ...
}
查看:GET /索引库名/_doc/文档id
删除:DELETE /索引库名/_doc/文档id
修改:方式一:全部修改,会删除旧文档,添加新文档
PUT /索引库名/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
// ...
}
方式二:增量修改,修改指定的字段名
POST /索引库名/_update/文档id
{
"doc": {
"字段名": "新的值",
}
}
4.1.Dynamic Mapping(动态映射)
当我们向ES中插入文档时,如果文档中字段没有对应的mapping,ES会帮助我们字段设置mapping,规则如下:
JSON类型 | Elasticsearch类型 |
字符串 |
•
日期格式字符串:
mapping
为
date
类型
•
普通字符串:
mapping
为
text
类型,并添加
keyword
类型子字段
|
布尔值 | boolean |
浮点数 | float |
整数 | long |
对象嵌套 | object,并添加properties |
数组 | 由数组中的第一个非空类型决定 |
空值 | 忽略 |
5.1.数据聚合
聚合常见的有三类:
-
桶(Bucket)聚合:用来对文档做分组
-
TermAggregation:按照文档字段值分组,例如按照品牌值分组、按照国家分组
-
Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组
-
-
度量(Metric)聚合:用以计算一些值,比如:最大值、最小值、平均值等
-
Avg:求平均值
-
Max:求最大值
-
Min:求最小值
-
Stats:同时求max、min、avg、sum等
-
-
管道(pipeline)聚合:其它聚合的结果为基础做聚合
注意:参加聚合的字段必须是keyword、日期、数值、布尔类型
5.1.1. Bucket聚合语法
GET /索引库名/_search
{
"size": 0, // 设置size为0,结果中不包含文档,只包含聚合结果
"aggs": { // 定义聚合
"brandAgg": { //给聚合起个名字
"terms": { // 聚合的类型,按照品牌值聚合,所以选择term
"field": "brand", // 参与聚合的字段
"size": 20 // 希望获取的聚合结果数量
}
}
}
}
5.1.2.聚合结果排序
默认情况下,Bucket聚合会统计Bucket内的文档数量,记为count,并且按照count降序排序。
我们可以指定order属性,自定义聚合的排序方式:
GET /索引库名/_search
{
"size": 0, // 设置size为0,结果中不包含文档,只包含聚合结果
"aggs": { // 定义聚合
"brandAgg": { //给聚合起个名字
"terms": { // 聚合的类型,按照品牌值聚合,所以选择term
"field": "brand", // 参与聚合的字段
"size": 20 // 希望获取的聚合结果数量
}
}
}
}
5.1.3.限定聚合结果
默认情况下,Bucket聚合是对索引库的所有文档做聚合,但真实场景下,用户会输入搜索条件,因此聚合必须是对搜索结果聚合。那么聚合必须添加限定条件。
我们可以限定要聚合的文档范围,只要添加query条件即可:
GET /索引库名/_search
{
"query": {
"range": {
"price": {
"lte": 200 // 只对200元以下的文档聚合
}
}
},
"size": 0,
"aggs": {
"brandAgg": {
"terms": {
"field": "brand",
"size": 20
}
}
}
}
5.2.Metric聚合语法
GET /索引库名/_search
{
"size": 0,
"aggs": {
"brandAgg": {
"terms": {
"field": "brand",
"size": 20
},
"aggs": { // 是brands聚合的子聚合,也就是分组后对每组分别计算
"score_stats": { // 聚合名称
"stats": { // 聚合类型,这里stats可以计算min、max、avg等
"field": "score" // 聚合字段,这里是score
}
}
}
}
}
}