es(2)—复杂的多条件查询(bool查询与constant_score查询)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了es(2)—复杂的多条件查询(bool查询与constant_score查询)相关的知识,希望对你有一定的参考价值。

参考技术A

接收如下参数:

在上述参数中,依旧可以使用bool关键字进行查询。

相关性得分的计算规则:
每一个子查询都独自计算doc的相关性得分,一旦他们的得分被计算出来,bool查询就将这些得分进行合并并且返回一个代表整个bool操作的得分。

查看测试用例:

由上图可知,filter仅仅是筛选条件,并不会计算_score,而should仅仅是计算_score,并不会进行筛选。

Filter不需要计算相关性算分,不需要按照相关分数进行排序,同时还自动缓存最常用filter的数据。性能好。
Query操作恰恰相反,会计算相关性算分,并且按照结果进行排序,无法缓存结果,性能不好。
故,在某些不需要相关性算分的查询场景,尽量使用FilterContext优化查询性能。

constant_score:本意(常量分数),可以将一个不变的常量应用到所有匹配的文档中。它常用于只需要执行一个filter而没有其他查询(例如评分查询)的情况下。term查询被放置在constant_score中,转换成不评分的filter。这种方式可以用来只有filter的bool查询中。

数据准备

其本质相当于:

只是bool中只有filter操作,故使用constant_score代替了filter操作,且为每一个子查询设置了常量分数。

由上述结果中也可以看出,_score的计算规则:每一个子查询都独自计算doc的相关性得分,一旦他们的得分被计算出来,bool查询就将这些得分进行合并并且返回一个代表整个bool操作的得分。

与使用constant_score的区别是,should参与评分计算,而我们设置的boost只是参与评分的权重比例。并不是一个具体的分数值。这也就是为何这种方式计算出来的score存在小数的原因。

ES查询语法

参考技术A 参数拼接到查询路劲中查询,查询可以不指定 type 的类型

查询结果部分字段说明:

value值部分会作为整体被查询, 不会被分词, 与match做区分, match的value是会被分词作匹配查询的.

返回的文档必须满足must子句的条件,并且参与计算分值

返回的文档必须满足filter子句的条件。但是不会像Must一样,参与计算分值

返回的文档可能满足should子句的条件。在一个Bool查询中,如果没有must或者filter,有一个或者多个should子句,那么只要满足一个就可以返回。minimum_should_match参数定义了至少满足几个子句, 默认情况是1

返回的文档必须不满足must_not定义的条件。
如果一个查询既有filter又有should,那么至少包含一个should子句。
bool查询也支持禁用协同计分选项disable_coord。一般计算分值的因素取决于所有的查询条件。
bool查询也是采用more_matches_is_better的机制,因此满足must和should子句的文档将会合并起来计算分值。

使用 _source 可以只查询需要展示的列, 相当于 sql 的 select offset,methodName from ...

from表示从第几行开始,size表示查询多少条文档。from默认为0,size默认为10,


聚合查询的结构:

举例说明:

比如求所有文档某个字段求最大、最小、和、平均值, 可以对某个field进行计算.

以avg为例, 计算offset在所有文档中的均值

运行结果:

该聚合一般域其它 single-value 聚合联合使用,比如在计算一个字段的平均值的时候,可能还会关注这个平均值是由多少个值计算而来。

例子:统计搜索结果中maiDianType字段出现的次数

搜索结果:

基于文档的某个值(可以是特定的字段,也可以通过脚本计算而来),计算文档非重复的个数(去重计数),相当于sql中的distinct。

例子: 统计搜索结果中maiDianType出现的种类

搜索结果: maiDianType共有6种值

基于文档的某个值(可以是特定的数值型字段,也可以通过脚本计算而来),计算出一些统计信息(min、max、sum、count、avg5个值)。

例子: 基于useTime进行值统计
ps: 这个例子中是基于脚本进行的统计

统计结果:

与stats功能相似, 比stats多4个统计结果: 平方和、方差、标准差、平均值加/减两个标准差的区间
例子:

结果:

对指定字段(脚本)的值按从小到大累计每个值对应的文档数的占比(占所有命中文档数的百分比),返回指定占比比例对应的值。默认返回[ 1, 5, 25, 50, 75, 95, 99 ]分位上的值,也可以指定分位置.

例子:

结果:

ps:
"1.0":30 代表: useTime<30的, 占比1%
"99.0":237 代表: useTime<237的, 占比99%

例子: 指定聚合的百分比

查询结果:

词聚合。基于某个field,该 field 内的每一个【唯一词元】为一个桶,每个桶内可以做再次聚合.

列子: 以prodSubNo的每个值作为聚合, 聚合结果默认排序为从大到小

搜索结果:

doc_count_error_upper_bound: //文档计数的最大偏差值
sum_other_doc_count: , //未返回的其他项的文档数

列子: 以prodSubNo的每个值作为聚合, 得到的桶继续做avg子聚合, 得到每个prodSubNo下的useTime的avg聚合结果

搜索结果:

基于一个条件,来对当前的文档进行过滤的聚合。

例子: 对查询结果进行过滤, prodSubNo=601001聚合过滤, 可对过滤后的内容进行子聚合查询, 这里使用stats统计聚合

查询结果:

基于多个过滤条件,来对当前文档进行【过滤】的聚合,每个过滤都包含所有满足它的文档(多个bucket中可能重复),先过滤再聚合。

例子: 使用prodSubNo=601001和maiDianType=script分别对索引结果进行过滤

搜索结果:

范围分组聚合。基于某个值(可以是 field 或 script),以【字段范围】来桶分聚合。范围聚合包括 from 值,不包括 to 值(区间前闭后开)。

例子: 对于useTime字段值进行0-20和20-40范围内的聚合
ps: 对范围聚合后的结果,还可以进行子聚合

搜索结果:

以上是关于es(2)—复杂的多条件查询(bool查询与constant_score查询)的主要内容,如果未能解决你的问题,请参考以下文章

Es7.x使用RestHighLevelClient进行查询操作

ElasticSearch 使用详解:组合查询怎么玩

ES查询语法

es 按条件查询数据总条数

es 按条件查询数据总条数

ES:多值(in)查询和条件批量删除