PassJava 开源项目(二十)之 详解 Elasticsearch 高级检索玩法
Posted 公众号_悟空聊架构
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PassJava 开源项目(二十)之 详解 Elasticsearch 高级检索玩法相关的知识,希望对你有一定的参考价值。
PassJava (佳必过) 项目全套学习教程连载中,关注公众号悟空聊架构第一时间获取。
文档在线地址: www.passjava.cn
ElastiscSearch 系列文章的内容如下:
ElasticSearch 高阶检索玩法
5.1 两种查询方式
5.1.1 URL 后接参数
GET bank/_search?q=*&sort=account_number: asc
``/_search?q=*&sort=account_number: asc
查询出所有数据,共 1000 条数据,耗时 1ms,只展示 10 条数据 ( ES 分页 )
属性值说明:
took – ES 执行搜索的时间 ( 毫秒 )
timed_out – ES 是否超时
_shards – 有多少个分片被搜索了,以及统计了成功/失败/跳过的搜索的分片
max_score – 最高得分
hits.total.value - 命中多少条记录
hits.sort - 结果的排序 key 键,没有则按 score 排序
hits._score - 相关性得分
参考文档:
https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started-search.html
5.1.2 URL 加请求体进行检索 ( QueryDSL )
请求体中写查询条件
语法:
GET bank/_search
"query":"match_all": ,
"sort": [
"account_number": "asc"
]
示例:查询出所有,先按照 accout_number 升序排序,再按照 balance 降序排序
5.2 详解 QueryDSL 查询
5.2.1 全部匹配 match_all
示例:查询所有记录,按照 balance 降序排序,只返回第 11 条记录到第 20 条记录,只显示 balance 和 firstname 字段。
GET bank/_search
"query":
"match_all":
,
"sort": [
"balance":
"order": "desc"
],
"from": 10,
"size": 10,
"_source": ["balance", "firstname"]
5.2.2 匹配查询 match
- 基本类型 ( 非字符串 ) ,精确匹配
GET bank/_search
"query":
"match": "account_number": "30"
- 字符串,全文检索
GET bank/_search
"query":
"match":
"address": "mill road"
查到了 32 条记录,最高的一条记录是 Address = "990 Mill Road",得分:8.926605. Address="198 Mill Lane" 评分 5.4032025,只匹配到了 Mill 单词。
5.2.3 短语匹配 match_phase
将需要匹配的值当成一个整体单词 ( 不分词 ) 进行检索
GET bank/_search
"query":
"match_phrase":
"address": "mill road"
5.2.4 多字段匹配 multi_match
GET bank/_search
"query":
"multi_match":
"query": "mill land",
"fields": [
"state",
"address"
]
5.2.5 复合查询 bool
搭配使用 must,must_not,should
must: 必须达到 must 指定的条件。 ( 影响相关性得分 )
must_not: 必须不满足 must_not 的条件。 ( 不影响相关性得分 )
should: 如果满足 should 条件,则可以提高得分。如果不满足,也可以查询出记录。 ( 影响相关性得分 )
示例:查询出地址包含 mill,且性别为 M,年龄不等于 28 的记录,且优先展示 firstname 包含 Winnie 的记录。
GET bank/_search
"query":
"bool":
"must": [
"match":
"address": "mill"
,
"match":
"gender": "M"
],
"must_not": [
"match":
"age": "28"
],
"should": [
"match":
"firstname": "Winnie"
]
5.2.6 filter 过滤
GET bank/_search
"query":
"bool":
"filter": [
"range":
"age":
"gte":18,
"lte":40
]
5.2.7 term 查询
非 text 字段精确匹配
GET bank/_search
"query":
"term":
"age": "20"
5.2.8 aggregations 聚合
聚合语法:
"aggregations" :
"<聚合名称 1>" :
"<聚合类型>" :
<聚合体内容>
[,"元数据" : [<meta_data_body>] ]?
[,"aggregations" : [<sub_aggregation>]+ ]?
[,"聚合名称 2>" : ... ]*
- 示例 1:搜索 address 中包含 big 的所有人的年龄分布 ( 前 10 条 ) 以及平均年龄,以及平均薪资
GET bank/_search
"query":
"match":
"address": "mill"
,
"aggs":
"ageAggr":
"terms":
"field": "age",
"size": 10
,
"ageAvg":
"avg":
"field": "age"
,
"balanceAvg":
"avg":
"field": "balance"
检索结果如下所示:
hits 记录返回了,三种聚合结果也返回了,平均年龄 34 随,平均薪资 25208.0,品骏年龄分布:38 岁的有 2 个,28 岁的有一个,32 岁的有一个
如果不想返回 hits 结果,可以在最后面设置 size:0
GET bank/_search
"query":
"match":
"address": "mill"
,
"aggs":
"ageAggr":
"terms":
"field": "age",
"size": 10
,
"size": 0
- 示例 2:按照年龄聚合,并且查询这些年龄段的平均薪资
从结果可以看到 31 岁的有 61 个,平均薪资 28312.9,其他年龄的聚合结果类似。
- 示例 3:按照年龄分组,然后将分组后的结果按照性别分组,然后查询出这些分组后的平均薪资
GET bank/_search
"query":
"match_all":
,
"aggs":
"ageAggr":
"terms":
"field": "age",
"size": 10
,
"aggs":
"genderAggr":
"terms":
"field": "gender.keyword",
"size": 10
,
"aggs":
"balanceAvg":
"avg":
"field": "balance"
,
"size": 0
从结果可以看到 31 岁的有 61 个。其中性别为 M
的 35 个,平均薪资 29565.6,性别为 F
的 26 个,平均薪资 26626.6。其他年龄的聚合结果类似。
5.2.9 Mapping 映射
- 定义哪些字符串属性应该被看做全文本属性 ( full text fields )
- 定义哪些属性包含数字,日期或地理位置
- 定义文档中的所有属性是否都能被索引 ( _all 配置 )
- 日期的格式
- 自定义映射规则来执行动态添加属性
Elasticsearch7 去掉 tpye 概念:
关系型数据库中两个数据库表示是独立的,即使他们里面有相同名称的列也不影响使用,但 ES 中不是这样的。elasticsearch 是基于 Lucence 开发的搜索引擎,而 ES 中不同 type 下名称相同的 field 最终在 Lucence 中的处理方式是一样的。
为了区分不同 type 下的同一名称的字段,Lucence 需要处理冲突,导致检索效率下降
ES7.x 版本:URL 中的 type 参数为可选。
ES8.x 版本:不支持 URL 中的 type 参数
所有类型可以参考文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
- 查询索引的映射
如查询 my-index 索引的映射
GET /my-index/_mapping
返回结果:
"my-index" :
"mappings" :
"properties" :
"age" :
"type" : "integer"
,
"email" :
"type" : "keyword"
,
"employee-id" :
"type" : "keyword",
"index" : false
,
"name" :
"type" : "text"
- 创建索引并指定映射
如创建 my-index 索引,有三个字段 age,email,name,指定类型为 interge, keyword, text
PUT /my-index
"mappings":
"properties":
"age": "type": "integer" ,
"email": "type": "keyword" ,
"name": "type": "text"
返回结果:
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "my-index"
- 添加新的字段映射
如在 my-index 索引里面添加 employ-id 字段,指定类型为 keyword
PUT /my-index/_mapping
"properties":
"employee-id":
"type": "keyword",
"index": false
- 更新映射
- 数据迁移
POST _reindex
"source":
"index": "twitter"
,
"dest":
"index": "new_twitter"
个人网站:www.passjava.cn
以上是关于PassJava 开源项目(二十)之 详解 Elasticsearch 高级检索玩法的主要内容,如果未能解决你的问题,请参考以下文章
PassJava 开源项目(十六):Elasticsearch 简介
PassJava 开源 : Spring Cloud 整合Gateway网关 #私藏项目实操分享#
PassJava 开源 : Spring Cloud 整合 Nacos 配置中心 #私藏项目实操分享#
PassJava 开源 : 整合 OpenFeign实现声明式远程调用 #私藏项目实操分享#