今天来了解下 Elasticsearch(以下简称 ES) 中的 Query 和 Filter。

在 ES 中,提供了 Query 和 Filter 两种搜索:

  • Query Context:会对搜索进行相关性算分
  • Filter Context:不需要相关性算分,能够利用缓存来获得更好的性能

举一个栗子,比如需要搜索一场电影,包含以下信息:

评论中包含了烧脑,评分高于 8 分,同时上映时间在 2010 到 2020 之间。

所以这个搜索包括了三个判断逻辑,针对三个不同的字段进行查询,如果需要满足这样的查询需求,在 ES 当中提供了 bool 查询,一个 bool 查询可以包含一个或多个查询字句,支持以下四种查询:

  • must:必须匹配,贡献算分
  • should:选择性匹配,贡献算分
  • must_not:查询字句,必须不能匹配
  • filter:必须匹配,不贡献算分

上图是一个 bool 查询,是对用户(user)进行搜索,城市必须是北京(beijing) ,性别必须是男(man),这个采用的是 filter,说明这个对算分是不会产生影响的,must_not 是一个 range 的查询:年龄大于等于 35 岁;should 里是一个数组,说明这个 should 中可以写多个条件,只要用户的名字是这两个中的一个就是满足条件的。

其实,bool 查询的子查询可以任意顺序出现,并且可以嵌套多个查询。

另外,should 的使用分两种情况:

  • bool 查询中只包含 should,不包含 must 查询
  • bool 查询中同时包含 should 和 must 查询

下面让我们来看看这两种情况有何不同?

如果在 bool 查询中没有 must 子句,should 中必须至少满足一条查询(可以通过 minimum_should_match 来设置满足条件的个数或者百分比)。

同时包含 should 和 must 时,文档不必满足 should 中的条件,但是如果满足条件,会增加相关性算分。

Filter Context

上面说到了 filtermust_not 是不会影响算分的,通过查询结果中可以看到 _score 都是 0。

Query Context

采用 should 查询,会进行算分处理,结果如下图所示:

同时,查询语句的结构,也会对相关度算分产生影响:

  • 同一层级的查询字段,权重是相同的
  • 通过嵌套 bool 查询,可以改变对算分的影响

Boost & Boosting Query

相关度还可以通过对某个字段设置 boost 的值来进行控制:

  • 当 boost > 1 时,打分的相关度相对性提升
  • 当 0 < boost < 1 时,打分的权重相对性降低
  • 当 boost < 0 时,贡献负分

或者使用 ES 提供的 Boosting Query 进行查询:

首先插入几条数据用于测试:

POST /product/_bulk
{ "index": { "_id": 1 }}
{ "content":"Apple Mac" }
{ "index": { "_id": 2 }}
{ "content":"Apple iPad" }
{ "index": { "_id": 3 }}
{ "content":"Apple Juice" }

如下图所示,左边就是一个 Boosting Query,positive 查询意思是如果 content 中包含 Apple 会按照原始的相关性分数进行打分,negative 查询则是满足 positive 查询同时满足 negative 查询(content 中包含 Juice)的会按照原始的相关性分数乘以 negative_boost 进行打分,negative_boost 是用于降低与 negative 匹配文档的相关性算分的。

如右图所示,这个的查询结果为三条数据,可以发现 Apple MacApple iPad 的相关性算分相同,都排在前面,而 Apple Juice 的相关性算分是其他两个的 0.1 倍,排在最后。

用一个表格来总结下 Query Context 和 Filter Context 的区别:

Context Type 含义 使用方式
Query 查找与查询语句最匹配的文档,对所有文档进行相关性算分并排序 query;bool 中的 must 和 should
Filter 查找与查询语句相匹配的文档 bool 中的 filter 和 must_not;constant_score 中的 filter

filter 不需要计算相关性算分,不需要按照相关分数进行排序,同时还有内置的自动 cache 最常使用的 filter 的数据,而 query 相反,需要计算相关性算分,按照分数进行排序,而且无法 cache 结果,因此在某些不需要相关性算分的查询场景,尽量使用 Filter Context 来让查询更加高效。

下图为 eBay 对于 Filter Context 和 Query Context 的性能比较:

那么 filter 的 cache 是怎么做的呢?

ES 会构建一个文档匹配过滤器的位集 bitset(用来标识一个文档对一个 filter 条件是否匹配,如果匹配就是 1,不匹配就是 0),下次再有这个 filter 条件过来的时候就不用重新扫描倒排索引,反复生成 bitset,可以大幅度提升性能,另外当添加或更新文档时,这个 filter 的位集 bitset 也会更新。

总结

当用户输入多个条件进行查询的时候,可以使用 bool 查询,在 bool 查询中,filtermust_not 属于 Filter Context,不会对算分结果产生影响;mustshould 属于 Query Context,会对结果算分产生影响。

在 bool 查询中,查询结构是对相关性算分有影响的,可以通过嵌套的方式修改不同字段在查询中的权重以及直接通过指定字段的 boost 值来控制在搜索中的权重,另外使用 Boosting Query 可以提升搜索的精准性,同时也可以将更多的搜索显示在结果中。

最好的关系就是互相成就,大家的点赞、在看、分享、留言就是我创作的最大动力。

参考

Elastic Stack从入门到实践

Elasticsearch核心技术与实战

Elasticsearch顶尖高手系列-快速入门篇

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-boosting-query.html

Elasticsearch 之 Filter 与 Query 有啥不同?的更多相关文章

  1. ElasticSearch教程——filter与query对比(转学习使用)

    一.数据准备 PUT /company/employee/2 { "address": { "country": "china", &quo ...

  2. ES之六:ElasticSearch中Filter和Query的异同

    如下例子,查找性别是女,所在的州是PA,过滤条件是年龄是39岁,balance大于等于10000的文档: { "query": { "bool": { &quo ...

  3. ElasticSearch中Filter和Query的异同

    如下例子,查找性别是女,所在的州是PA,过滤条件是年龄是39岁,balance大于等于10000的文档: { "query": { "bool": { &quo ...

  4. Elasticsearch学习笔记(十二)filter与query

    一.keyword 字段和keyword数据类型    1.测试准备数据 POST /forum/article/_bulk { "index": { "_id" ...

  5. Elasticsearch由浅入深(九)搜索引擎:query DSL、filter与query、query搜索实战

    search api的基本语法 语法概要: GET /_search {} GET /index1,index2/type1,type2/_search {} GET /_search { , } h ...

  6. elasticsearch的javaAPI之query

    elasticsearch的javaAPI之query API the Search API同意运行一个搜索查询,返回一个与查询匹配的结果(hits). 它能够在跨一个或多个index上运行, 或者一 ...

  7. ElasticSearch7.3学习(二十一)----Filter与Query对比、使用explain关键字分析语法

    1.数据准备 首先创建book索引 PUT /book/ { "settings": { "number_of_shards": 1, "number ...

  8. Event filter with query "SELECT * FROM __InstanceModi

    Event filter with query "SELECT * FROM __InstanceModi     问题描述: Details -Event filter with quer ...

  9. es中filter和query的对比

    1.filter与query示例PUT /company/employee/2{ "address": { "country": "china&quo ...

随机推荐

  1. Spring框架之spring-webmvc源码完全解析

    Spring框架之spring-webmvc源码完全解析 Spring框架提供了构建Web应用程序的全功能MVC模块.Spring MVC分离了控制器.模型对象.分派器以及处理程序对象的角色,支持多种 ...

  2. Java基础--接口回调(接口 对象名 = new 类名)理解

    接口 对象名1 = new 类名和类名 对象名2 = new 类名的区别是什么? 实例 /** *Person.java 接口 */ public interface Person { void in ...

  3. 使用javafx开发一款桌面个性化软件

    本来笔者只是打算开发一个显示在桌面的cpu和内存监控工具,没想到迭代了几次版本之后变成了桌面个性化工具了. 目前实现功能: cpu和内存的实时监控 开机自动启动 自定义logo 自定义主题颜色 鼠标拖 ...

  4. 借助Docker搭建JMeter+Grafana+Influxdb监控平台

    我们都知道Jmeter提供了原生的结果查看,既然有原生的查看结果,为什么还要多此一举使用其他工具进行查看呢,除了查看内容丰富外还有最主要的原因:Jmeter提供的查看结果插件本身是比较消耗性能的,所以 ...

  5. 【C++】《C++ Primer 》第四章

    第四章 表达式 一.基础 重载运算符:当运算符作用在类类型的运算对象时,用户可以自行定义其含义. 左值和右值: C中:左值可以在表达式左边,右值不能. C++中:当一个对象被用作右值的时候,用的是对象 ...

  6. 详细的String源码解析

    我们常常把String类型的字符串作为HashMap的key,为什么要这样做呢? 因为String是不可变的,一旦初始化就不再改变了,如果被修改将会是一个新对象. @Test public void ...

  7. Docker 镜像仓库使用(六)

    阿里云docker 容器镜像服务: www.aliyun.com 1 服务开通 (开通的时候要求创建密码请牢记此密码) 2 创建命名空间 3 创建镜像仓库 4 linux 客户端登录 登录: dock ...

  8. Linux学习笔记 | 配置Samba

    Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的一种通 ...

  9. SQL中的主键,候选键,外键,主码,外码

    1.码=超键:能够唯一标识一条记录的属性或属性集. 标识性:一个数据表的所有记录都具有不同的超键 非空性:不能为空 有些时候也把码称作"键" 2.候选键=候选码:能够唯一标识一条记 ...

  10. Nginx 路由转发和反向代理 location 配置

    Nginx 配置的三种方式 第一种直接替换 location 匹配部分 第二种 proxy_pass 的目标地址,默认不带 /,表示只代理域名,url 和参数部分不会变(把请求的 path 拼接到 p ...