目录
1. ElasticSearch之查询返回结果各字段含义
2. match 查询
3. term查询
4. terms 查询
5. range 范围
6. 布尔查询
6.1 filter加快查询效率的原因
7. boosting query(提高查询)
8. dis_max(最佳匹配查询)
9. 分页
10. 聚合查询【内含实际的demo】
1. ElasticSearch之查询返回结果各字段含义
执行命令:索引库名称/_search
空搜索的结果为:
{
"took": 2, # 该命令请求花费了多长时间,单位:毫秒。
"timed_out": false, # 搜索是否超时
"_shards": { # 搜索分片信息
"total": 3, # 搜索分片总数
"su***essful": 3, # 搜索成功的分片数量
"skipped": 0, # 没有搜索的分片,跳过的分片
"failed": 0 # 搜索失败的分片数量
},
"hits": { # 搜索结果集。需要的一切数据都是从hits中获取
"total": 21798, # 返回多少条数据
"max_score": 1, #返回结果中,最大的匹配度分值
"hits": [ # 默认查询前十条数据,根据分值降序排序,这里为了节省地方,把默认查询的前十条数据删了9条,只剩下一条数据
{
"_index": "", # 索引库名称
"_type": "", # 类型名称
"_id": "", # 该条数据的id
"_score": 1, # 关键字与该条数据的匹配度分值
"_routing": "", # routing参数是一个可选参数,默认使用文档的_id值,用于计算文档所属分片
"_source": { # 索引库中类型,返回结果字段,不指定的话,默认全部显示出来
"id": 1,
"orderNo": "",
"appId": "",
"***ponentAppId": "",
"settleNo": "",
"outSettleNo": "",
"settleAmount": 5,
"orderAmount": 7,
"settleStatus": 3,
"paymentChannel": 1,
"version": 2,
"settleTime": ,
"createTime": ,
"updateTime": ,
"promotionA***ountId": "",
"invoiceStatus": 1,
"promotionTypeValue": 0,
"***missionRateFeeCentAmount": 0,
"***missionChargeFeeCentAmount": 0,
"promotionFeeCentAmount": 2,
"developerPromotionFeeCentAmount": 0,
"promotionType": ""
}
}
]
}
}
- 按照从上到下的顺序,一共四个返回值,took,timed_out,_shards,hits。
- took
- 该命令请求花费了多长时间,单位:毫秒。
- timed_out
- 搜索是否超时。
- shards
- 搜索分片信息。
- total
- 搜索分片总数。
- su***essful
- 搜索成功的分片数量。
- skipped
- 没有搜索的分片,跳过的分片。
- failed
- 搜索失败的分片数量。
- hits
- 搜索结果集,需要的一切数据都是从hits中获取。
- total
- 返回多少条数据。
- max_score
- 返回结果中,最大的匹配度分值。
- hits
- 默认查询前十条数据,根据分值降序排序。
- _index
- 索引库名称。
- _type
- 类型名称。
- _id
- 该条数据的id。
- _score
- 关键字与该条数据的匹配度分值。
- _source
- 索引库中类型,返回结果字段,不指定的话,默认全部显示出来。
2. match 查询
-
匹配查询 match 是个 核心 查询。无论需要查询什么字段, match 查询都应该会是首选的查询方式。它是一个高级 全文查询 ,这表示它既能处理全文字段(包括支持分词的字段),又能处理精确字段
-
match 查询主要的应用场景就是进行全文搜索
{
"query": {
"match": {
"appId": "xxxx"
}
}
}
match本质上是对term组合,所以上面的语句换成term依然能够执行
{
"query": {
"term": {
"appId": "xxxx"
}
}
}
3. term查询
-
term 查询, 可以用它处理数字(numbers)、布尔值(Booleans)、日期(dates)以及文本(text)
-
用 trem 搜索字符串时 要将字段设置成 not_analyzed 无需分析的。不然es会将字符串进行分词,分词结果建立索引,在用trem进行精确查找时找不到任何文档
-
对应的 QueryBuilder class 是TermQueryBuilder
-
具体方法是 QueryBuilders.termQuery()
{
"query": {
"term": {
"appId": "xxxx"
}
}
}
4. terms 查询
-
terms 查询允许指定多个值进行匹配。如果这个字段包含了指定值中的任何一个值,就表示该文档满足条件。 比如我们想要查找价格字段值为 $20 或 $30 的文档则可以使用trems;
-
按照读个分词term匹配,它们是or的关系
-
对应的 QueryBuilder class 是 TermsQueryBuilder
- 具体方法是 QueryBuilders.termsQuery()
{
"query": {
"terms": {
"appId": ["xxxx", "xxxx"]
}
}
}
5. range 范围
-
常常被用在数字或者日期范围的查询
Search Query |
QueryBuilder Class |
Method in QueryBuilders |
Range |
RangeQueryBuilder |
QueryBuilders.rangeQuery() |
{
"query": {
"range": {
"createTime": {
"gte": 1661409996661,
"lte": 1661409996661
}
}
}
}
6. 布尔查询
- 通过布尔逻辑将较小的查询组合成较大的查询。
- 概念
- Bool查询语法有以下特点
- 子查询可以任意顺序出现
- 可以嵌套多个查询,包括bool查询
- 如果bool查询中没有must条件,should中必须至少满足一条才会返回结果。
- bool查询包含四种操作符,分别是must,should,must_not,filter。他们均是一种数组,数组里面是对应的判断条件。
- must: 必须匹配。贡献算分
- must_not:过滤子句,必须不能匹配,但不贡献算分
- should: 选择性匹配,至少满足一条。贡献算分
- filter: 过滤子句,必须匹配,但不贡献算分,所以比must会更快!
- Bool查询语法有以下特点
{
"query": {
"bool": {
"must": [
{
"term": {
"appId": "xxxx"
}
},
{
"term": {
"paymentChannel": 1
}
},
{
"term": {
"settleStatus": 3
}
},
{
"term": {
"promotionA***ountId": ""
}
},
{
"range": {
"createTime": {
"from": 1658741630780,
"to": 1661420030780,
"include_lower": true,
"include_upper": true
}
}
}
]
}
}
}
6.1 filter加快查询效率的原因
-
query context
-
query context关注的是,文档到底有多匹配查询的条件,这个匹配的程度是由相关性分数决定的,分数越高自然就越匹配。所以这种查询除了关注文档是否满足查询条件,还需要额外的计算相关性分数.
-
-
filter context
-
filter context关注的是,文档是否匹配查询条件,结果只有两个,是和否。没有其它额外的计算。它常用的一个场景就是过滤时间范围。
-
并且filter context会自动被ES缓存结果,效率进一步提高。
-
对于bool查询,must使用的就是query context,而filter使用的就是filter context。
-
我们可以通过一个示例验证下。继续使用第一节的例子,我们通过kibana自带的search profiler来看看ES的查询的详细过程。
-
-
那么 filter 的 cache 是怎么做的呢?
-
ES 会构建一个文档匹配过滤器的位集 bitset(用来标识一个文档对一个 filter 条件是否匹配,如果匹配就是 1,不匹配就是 0),下次再有这个 filter 条件过来的时候就不用重新扫描倒排索引,反复生成 bitset,可以大幅度提升性能,另外当添加或更新文档时,这个 filter 的位集 bitset 也会更新。
-
{
"query": {
"bool": {
"must": [
{
"term": {
"appId": "xxxx"
}
},
{
"term": {
"paymentChannel": 1
}
},
{
"term": {
"settleStatus": 3
}
},
{
"term": {
"promotionA***ountId": ""
}
}
],
"filter": {
"range": {
"createTime": {
"from": 1658741630780,
"to": 1661420030780,
"include_lower": true,
"include_upper": true
}
}
}
}
}
}
7. boosting query(提高查询)
-
用来控制(提高或降低)复合查询中子查询的权重。
-
不同于bool查询,bool查询中只要一个子查询条件不匹配那么搜索的数据就不会出现。而boosting query则是降低显示的权重/优先级(即score)。
-
比如搜索逻辑是 name = 'apple' and type ='fruit',对于只满足部分条件的数据,不是不显示,而是降低显示的优先级(即score)
-
~positive(积极的,加分):
-
只有匹配上positive的查询的内容,才会被放到返回的结果集中。
-
-
~negative(消极的,减分):
-
如果匹配上positive并且也匹配上了negative,就可以降低这样的文档score。
-
-
~negative_boost:
-
指定系数,必须小于1.0 ,那么匹配到的内容会将分数乘以当前系数;(这是个系数,因为你要控制分数,那要怎么控制呢?就是乘以系数来控制分数大小)
-
{
"query": {
"boosting": {
"positive": {
"term": {
"appId": "xxxx"
}
},
"negative": {
"term": {
"orderNo": "xxxx"
}
},
"negative_boost": 0.5
}
}
}
8. dis_max(最佳匹配查询)
-
dis_max query
-
叫做分离最大化查询,它会将任何与查询匹配的文档都作为结果返回,但是只是将其中最佳匹配的评分作为最终的评分返回。
-
-
dis_max 条件的计算分数
-
分数 = 第一个匹配条件分数 + tie_breaker * 第二个匹配的条件的分数 ...
-
"query": {
"dis_max": {
"queries": [
{
"term": {
"appId": "xxxx"
}
},
{
"term": {
"paymentChannel": 1
}
},
{
"range": {
"createTime": {
"from": 1658741630780,
"to": 1661420030780,
"include_lower": true,
"include_upper": true
}
}
}
],
"tie_breaker": 0
}
}
9. 分页
-
通过 from 和 size 就可以执行分页查询。from 指明了分页查询返回的结果的起始位置,而size参数则指明了分页查询的页容量。
{
"from": 0,
"size": 1,
"query": {
"bool": {
"must": [
{
"term": {
"appId": "xxxx"
}
},
{
"term": {
"paymentChannel": 1
}
},
{
"term": {
"settleStatus": 3
}
},
{
"term": {
"promotionA***ountId": ""
}
},
{
"range": {
"createTime": {
"from": 1658741630780,
"to": 1661420030780,
"include_lower": true,
"include_upper": true
}
}
}
]
}
}
}
10. 聚合查询【内含实际的demo】
根据appId查询昨日结算成功的指定支付渠道的结算总金额
{
"query": {
"bool": {
"must": [
{
"term": {
"appId": "xxxx"
}
},
{
"term": {
"paymentChannel": 1
}
},
{
"term": {
"settleStatus": 3
}
},
{
"term": {
"promotionA***ountId": ""
}
},
{
"range": {
"createTime": {
"from": 1658741630780,
"to": 1661420030780,
"include_lower": true,
"include_upper": true
}
}
}
]
}
},
"aggs": {
"total_amount": {
"sum": {
"field": "settleAmount"
}
}
},
"size": 0
}