MYSQL查询的时候遇到的问题
- 数据量大的时候 索引失效 =查询性能低
- 功能比较弱
解决的方案
倒排索引(es)
对文档的内容进行分词,对词条创建索引,记录词条所在的文档信息根据词条查询到文档的id 从而查到文档
- 文档:每一条数据就是一条文档
- 词条:文档按照语义分成的词语
正向索引
根据文档的id创建索引 查询词条必须先找到文档完了判断是否包含词条
实现的技术
Lucene(是Apache的开源搜索引擎类库,提供了搜索引擎的核心API)
ES
文档
es是面向文档存储的可以是数据库中的一条商品数据订单信息,文档会被序列化为json后存储在es中
- table index 索引就是文档的集合相当于数据库中的表
- row document文档就是一条条数据相当于数据库中的行
- cloumn field 字段就是json文档中的字段相当于数据库中的列
- schema mapping mappin(映射)是索引中文档的约束相当于数据库的表结构
- sql dsl dsl是es提供的json风格的请求语句用来操作es实现crud
es和mysql的关系
mysql:擅长事务类型操作,可以确保数据的安全和一致性
es:擅长海量数据的搜索、分析、计算
Mapping中的属性
- type
字符串:text能分词 keyword:不能分词
数字:long,short,interger,double,float…
布尔:boolen
日期:date
对象:object
index:如果需要根据该字段进行搜索设置为true(默认为true)
analyzer:当type为text需要指定分词器
分词器的作用:
- 创建索引对文档分词
- 用户搜索对输入的内容分词
IK分词器的模式 - ik_smart:智能切分,粗粒度
- ik_max_word:最细切分,细粒度
properties:字段的子字段
通过DSL对索引文档CRUD
索引:
增PUT /indexName
删DELETE /indexName
改:不能修改已经存在的域
先删除后新增
查GET /indexName
文档:
增:POST /indexName/_doc/docId
删:DELETE /indexName/_doc/docId
改:
全量修改(删除旧文档添加新文档
)
增量修改(修改指定的字段)
差:GET /indexName/_doc/docId
RestApi
在java中使用es的步骤
- 导入依赖
- 在配置文件中修改yml文件 spring.elasticsearch.uris
- 在需要操作的es类中注入对象
@Autowired
private RestHighLevelClient client;
对索引crud
通过调用 client.indices()
增:creat
删:delete
改:直接通过那个set设置
查:get
对文档crud
通过client
增:index
删:delete
查:get
改:全量:index
增量:update
批量:bulk
DQL查询分类
常见的查询类型:
- 查询所有 :查询出来所有的数据一般作为测试
- 全文检索(full text)查询:利用分词器对用户输入内容分词 然后去倒排索引库中匹配
- 精确查询:根据精确词条值查找数据一般找keywored数值 日期 boolean等字段
- 地理(geo):根据经纬度查询
- 复合(compound)查询:可以吧上面的各种查询组合起来合并查询条件
查询基本语法:
全文检索查询
match查询:全文检索查询的一种 会对用户输入的内容分词然后去倒排索引库检索
multi_match:和match相似 允许插入多个字段(参与查询的字段越多 查询性能越差)
精确查询
精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词
-
term:根据词条精确值查询 一般搜索keyword类型、数值类型、布尔类型、日期类型字段
-
range:根据值的范围查询 可以是数值、日期的范围
term:
range:
地理查询
根据经纬度查询
geo_bounding_box:查询geo_point值落在某个矩形范围的所有文档
geo_distance:查询到指定中心点小于某个距离值的所有文档
复合查询:复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑
fuction sorce:算分函数查询 可以控制文档相关性算分 控制文档的排名
function score query定义的三要素是什么?
- 过滤条件:那些文档要加分
- 算分函数:如何计算function scorce
- 加权方式:function score和query score 如何运算
Boolean Query
布尔查询是一个或多个查询子句的组合 子查询的组合方式有
### 对搜索的结果处理
-
排序:默认是根据相关度算分(_score)来排序。可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
-
分页:默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。
深度分页问题:
如果搜索页数过深,或者结果集(from + size)越大,对内存和CPU的消耗也越高。因此ES设定结果集查询的上限是10000
解决方案: -
search after:分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式。
-
scroll:原理将排序数据形成快照,保存在内存。官方已经不推荐使用。
处理分页的方式 -
高亮 :就是在搜索结果中把搜索关键字突出显示。
高亮的原理 -
吧搜索结果中的关键字用标签标记出来
-
在页面添加css样式
RestClient查询文档
查询的基本步骤
1 创建searchRequest对象
2 准备Request.source()
- QueryBuilders构建查询条件
2)传入Requset.source()的query()方法
3 发送请求得到结果
4 解析结果(参考json结果从外到内层层解析)
全文检索查询
全文检索的match和multi_match查询与match_all的API基本一致。差别是查询条件,也就是query的部分。
同样是利用QueryBuilders提供的方法:
精确查询
精确查询常见的有term查询和range查询,同样利用QueryBuilders实现:
复合查询
精确查询常见的有term查询和range查询,同样利用QueryBuilders实现:
排序和分页
高亮
高亮API包括请求DSL构建和结果解析两部分
高亮结果解析
RestClient查询文档-结果处理
- 所有搜索dsl的构建一个api:SearchRequest的source()方法
- 高亮结果解析是参考json结果卓层解析
数据聚合
什么是聚合:
聚合可以实现对文档数据的统计、分析、运算。
聚合的种类
- 桶(Bucket)聚合:用来对文档做分组
1)TermAggregation:按照文档字段值分组
2)Date Histogram:按照日期阶梯分组,例:一周为一组 - 度量(Metric)聚合:用以计算一些值:最大 最小 平均值
1)AVG:平均
2)MAX:最大
3)MIN:最小
4)STATAS:同时求max、min、avg、sum等 - 管道(pipeline)聚合:其他聚合的结果为基础做聚合
参与聚合的字段应该是 - keyword
- 数值
- 日期
- 布尔
DSL实现Bucket聚合
统计所有酒店品牌
类型为term类型
聚合结果排序
默认情况bucket聚合会统计bucket内的文档数量 记为_count 按照降序排序
修改为升序排序
限定聚合范围
默认情况下:bucket聚合对索引库所有 的文档做聚合 我们可以限定聚合的文档范围只要添加query属性即可
aggs代表聚合,与query同级,此时query的作用是?
限定文档的范围
聚合必须的三要素是:
- 聚合的名称
- 聚合的类型
- 聚合字段
聚合可配置属性有
- size:指定聚合结果数量
- order:指定聚合结果排序方式
- field:指定聚合字段
实现Metrics聚合
球每个品牌的用户评分的min max avg 等值
stats聚合
RestAPI实现聚合
品牌聚合文章来源:https://www.toymoban.com/news/detail-754881.html
聚合结果分析
文章来源地址https://www.toymoban.com/news/detail-754881.html
自动补全
到了这里,关于ES(Elasticsearch 全文检索)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!