p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解
目录
- Elasticsearch
- 正向索引与倒排索引
- elasticsearch的一些概念
- IK分词器
- 索引库
- DSL进行CRUD
- RestClient操作索引库
- DSL查询语法
-
- 全文检索查询
- 精确查询
- 地理查询
- 复合查询
-
- [Function Score Query](#Function Score Query)
- [Boolean Query](#Boolean Query)
- 搜索结果处理、分页、高亮
- 数据聚合
Elasticsearch
ES(Elasticsearch),是一款功能强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容
而elasticsearch结合kibana、Logstash、Beats,即elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域
ELK中elasticsearch是elastic stack的核心,负责存储、搜索、分析数据;而Logstash、Beats主要负责数据抓取;kibana则是一个数据可视化的组件
elasticsearch底层实现为Lucene;Lucene是一个java语言的搜索引擎类库,其优势为易扩展与高性能(基于倒排索引),缺点为只限于java语言开发
相比于Lucene,elasticsearch的优势为支持分布式、可水平扩展,提供Restful接口,可被任何语言调用
正向索引与倒排索引
传统数据库(如MySQL)采用正向索引,例如给id创建索引,id则会形成B+树,用户根据id查询时会非常快,但是根据别的字段如Title字段则不适用,而且模糊匹配时会进行逐条扫描,效率很慢
这时便可使用倒排索引;
倒排索引创建时会生成一张新的表,其中有词条(term)、文档id两个字段
文档(document):每条数据就是一个文档
词条(term):文档按语义分成的词语
词条不能重复,有重复词条则记录文档id即可;保证了词条的唯一性
这时再给词条加唯一索引即可
正向索引与倒排索引的区别
正向索引:基于文档id创建索引,查询词条时必须先找到文档,然后判断是否包含词条
倒排索引:对文档内容分词,对词条创建索引,并记录词条所在文档的信息,查询时先根据词条查询到文档id,然后获取到文档
elasticsearch的一些概念
文档:
elasticsearch是面向文档存储的,可以是数据库中的一条商品数据,一个订单信息,文档数据会被序列化为json格式后存储在elasticsearch中
。
索引:相同类型(表结构相同,即文档结构相同)的文档的集合
映射:索引当中文档的字段约束信息,类似于表的结构约束;比如这个字段的类型是String,则值必须是String类型,这就是约束
概念对比
Mysql擅长 事务类型操作,可以确保数据的安全和一致性
而elasticsearch擅长海量数据的搜索、分析、计算
IK分词器
es在创建倒排索引时需要对文档分词,在搜索时,需要对用户输入内容分词,但默认的分词规则对中文处理并不友好,在处理中文分词时一般使用IK分词器
其有两种模式:ik_smart:最少切分、ik_max_word:最细切分
IK分词器拓展词条与停用词条
利用config目录的IkAnalyzer.cfg.xml文件添加拓展词典和停用词典
在词典中添加拓展词条或者停用词条
索引库
mapping映射属性
mapping是对索引库中文档的约束,常见的mapping属性包括
type: 字段数据类型,常见的简单类型有:
字符串: text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
数值: long、integer、short、byte、double、float
布尔:boolean
日期:date
对象:object
index: 是否创建索引,默认为trueanalyzer: 使用哪种分词器
properties: 该字段的子字段
DSL进行CRUD
索引库CRUD
ES中通过restfu请求操作索引库、文档。请求内容用DSL语句表示。
json
//创建索引库
PUT /qill7
{
"mappings": {
"properties": {
"标题": {
"type": "text",
"analyzer": "ik_smart"
},
"关键字": {
"type": "keyword",
"index": false
},
"作者": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
//查看索引库语法
GET /qill7
//删除索引库语法
DELETE /qill7
//索引库和mapping一旦创建无法修改,但是可以添加新的字段,语法如下:
PUT /索引库名/_mapping {
"properties":{
"新字段名":{
"type":"integer"
}
}
}
文档CRUD
json
# 新增文档
# POST /索引库名/_doc/文档id
POST /qill7/_doc/1
{
"标题":"9.3阅兵在北京召开",
"关键字":"阅兵",
"作者":"张三"
}
# 查询文档
GET /qill7/_doc/1
# 查询所有文档
GET /qill7/_search{}
# 删除文档
DELETE /qill7/_doc/1
# 修改文档
# 方法一:全部修改,会删除旧文档,添加新文档
POST /qill7/_doc/1
{
"标题":"9.3阅兵在北京召开",
"关键字":"阅兵",
"作者":"李四"
}
# 方法二:局部修改,修改指定字段值
POST /qill7/_update/1
{
"doc": {
"作者":"王五"
}
}
RestClient操作索引库
RestClient,用来简化各种语言组装DSL并发送http请求的流程
DSL查询语法
全文检索查询
全文检索查询,会对用户输入的内容分词,常用于搜索框搜索
精确查询
精确查询一般是查找keyword、数值、日期、boolean等字段,所以不会 对搜索条件分词。常见的有
term查询:根据词条精确匹配,一般搜索keyword类型、数值类型、布尔类型、日期类型字段
range查询:根据数值范围查询,可以是数值、日期的范围
地理查询
复合查询
复合查询可以将其它简单查询组合起来,实现更加复杂的搜索逻辑,例如:fuction score:算分函数查询,可以控制文档相关性算分,控制文档排名。例如百度竞价
当我们利用match查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列。
下面为两种相关性打分算法
TF-IDF:在elasticsearch5.0之前,会随着词频增加而越来越大
BM25:在elasticsearch5.0之后,会随着词频增加而增大,但增长曲线会趋于水平,更好一点
Function Score Query
当我们想推流一些文档时,就要修改其的相关性算分,而使用Function Score Query就可以对其进行修改,再根据新得到的算分排序
Boolean Query
布尔查询是一个或多个查询子句的组合。子查询的组合方式有
·must:必须匹配每个子查询,类似"与"
·should:选择性匹配子查询,类似"或"
·must_not:必须不匹配,不参与算分,类似"非"
·filter:必须匹配,不参与算分
搜索结果处理、分页、高亮
elasticsearch支持对搜索结果排序,默认是根据相关性算分(_score)来排序。可以排序的字段有:keyword类型、数值类型、地理坐标类型、日期类型等
elasticsearch默认情况下只返回top10的数据,想要查询更多数据就需要修改分页参数
elasticsearch中通过修改from、size参数来控制要返回的分页结果
针对深度分页,ES提供了两种解决方案:
· search after:分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式。
· scroll:原理将排序数据形成快照,保存在内存。官方已经不推荐使用。
高亮,就是在搜索结果中把搜索关键字突出显示
原理:将搜索结果中的关键字用标签标记出来,然后在页面中给标签添加CSS样式
数据聚合
聚合(aggregations)可以实现对文档数据的统计、分析、运算,常见的聚合有三类:
桶(bucket)聚合:用来对文档分组
TermAggregation:按照文档字段值分组
DateHistogram:按照日期阶梯分组,例如一周为一组,或者一月为一组
度量(Metric)聚合:用以计算一些值,比如:最大值、最小值、平均值等
Avg: 求平均值
Max: 求最大值
Min: 求最小值
Stats: 同时求max、min、avg、sum等
聚合字段不能分词,即不能为text字段
管道(pipeline)聚合:其他聚合的结果为基础做聚合
桶聚合
json
GET /qill7/_search
{ # 聚合字段名不能为text
"size":0, # 设置size为0,结果中不包含文档,只包含聚合结果
"aggs":{ # 定义聚合
"authorAgg":{ # 给聚合起个名字
"terms":{ # 聚合的类型,按照品牌值聚合,所以选择term
"field":"作者", # 参与聚合的字段
"size":20 # 希望获取的聚合结果数量
"order": {
"_count": "asc" # 按count升序排序
}
}
}
}
}
聚合必须的三要素:
· 聚合名称
· 聚合类型
· 聚合字段
聚合可配置属性有:
· size: 指定聚合结果数量
· order: 指定聚合结果排序方式
· field: 指定聚合字段
度量聚合
比如获取每个作者的点赞数的min、max、avg等值
json
GET /qill7/_search
{
"size":0,
"aggs":{
"authorAgg":{
"terms":{
"field":"作者",
"size":20 ,
"order": {
"likeAgg.sum":"asc"
}
},
"aggs":{
"likeAgg":{
"stats":{
"field": "点赞"
}
}
}
}
}
}