Elasticsearch查询之Disjunction Max Query

前言

Disjunction Max Query 又称最佳 best_fields 匹配策略,用来优化当查询关键词出现在多个字段中,以单个字段的最大评分作为文档的最终评分,从而使得匹配结果更加合理

写入数据

如下的两条例子数据:

docId: 1
title: java python go
content: java scaladocId: 2
title: kubernetes docker
content: java spring python

POST test01/doc/_bulk
{ "index" : { "_id" : "1" } }
{ "title" : "kubernetes docker", "content": "java spring python" }
{ "index" : { "_id" : "2" } }
{ "title" : "java python go", "content": "java scala" }

查询数据

GET test01/_search?
{"query": {"bool": {"should": [{"match": {"title": "java spring"}},{"match": {"content": "java spring"}}]}}
}

结果如下:

{"took" : 2,"timed_out" : false,"_shards" : {"total" : 6,"successful" : 6,"skipped" : 0,"failed" : 0},"hits" : {"total" : 2,"max_score" : 0.5753642,"hits" : [{"_index" : "test01","_type" : "doc","_id" : "2","_score" : 0.5753642,"_source" : {"title" : "java python go","content" : "java scala"}},{"_index" : "test01","_type" : "doc","_id" : "1","_score" : 0.5753642,"_source" : {"title" : "kubernetes docker","content" : "java spring python"}}]}
}

可以看到,两个 doc 的 score 一样,尽管从内容上看 id=1 的 数据更应该排在前面,但默认的排序策略是有可能会导致id=2 的数据排在 id=1 的前面。

原理分析

在 ES 的默认评分策略下,boolean 查询的score是所有 should 条件匹配到的评分相加,下面简化分析一下得分流程,真实评分会比这个复杂,但大致思路一致:

在 id=1 中数据,由于 title 无命中,但 content 匹配到了 2 个关键词,所以得分为 2.

在 id=2 中数据,其 title 命中 1 个关键词 ,并且其 content 也命中一个关键词,所以最后得分也为 2.

从而得出了最终结果两个 doc 的得分一样

dis_max 查询

使用 dis_max查询优化匹配机制,采用单字段最大评分,作为最终的 score

GET test01/_search?
{"query": {"dis_max": {"queries": [{"match": {"title": "java spring"}},{"match": {"content": "java spring"}}]}}
}

结果如下:

{"took" : 4,"timed_out" : false,"_shards" : {"total" : 6,"successful" : 6,"skipped" : 0,"failed" : 0},"hits" : {"total" : 2,"max_score" : 0.5753642,"hits" : [{"_index" : "test01","_type" : "doc","_id" : "1","_score" : 0.5753642,"_source" : {"title" : "kubernetes docker","content" : "java spring python"}},{"_index" : "test01","_type" : "doc","_id" : "2","_score" : 0.2876821,"_source" : {"title" : "java python go","content" : "java scala"}}]}
}

结果已经符合预期了

tie_breaker参数

前面的结果我们看到已经符合预期了,现在如果我们用 dis max 继续查询另一种 case:


GET test01/_search?
{"query": {"dis_max": {"queries": [{"match": {"title": "python scala"}},{"match": {"content": "python scala"}}]}}
}

结果如下:

"hits" : [{"_index" : "test01","_type" : "doc","_id" : "2","_score" : 0.2876821,"_source" : {"title" : "java python go","content" : "java scala"}},{"_index" : "test01","_type" : "doc","_id" : "1","_score" : 0.2876821,"_source" : {"title" : "kubernetes docker","content" : "java spring python"}}]

可以看到两者的评分又一样了,但从实际来说,我们肯定希望 id = 2 的文档的得分更高的,因为其在多个字段中都有命中,但因为 dis max的匹配评分机制,又导致忽略了其他字段的评分的贡献,这个时候就需要进一步优化了,在 dis max 里面可以使用 tie_breaker 参数来控制,tie_breaker的值默认是 0 ,其设置了tie_breaker参数之后,dis max 的工作原理如下:

  1. 从得分最高的匹配子句中获取相关性得分。
  2. 将任何其他匹配子句的分数乘以 tie_breaker 值。
  3. 将最高分数和其他子句相乘的分数进行累加,得到最终的排序 score 值。

改进后的查询语句如下:

GET test01/_search?
{"query": {"dis_max": {"queries": [{"match": {"title": "python scala"}},{"match": {"content": "python scala"}}],"tie_breaker": 0.4}}
}

查询结果:

"hits" : {"total" : 2,"max_score" : 0.40275493,"hits" : [{"_index" : "test01","_type" : "doc","_id" : "2","_score" : 0.40275493,"_source" : {"title" : "java python go","content" : "java scala"}},{"_index" : "test01","_type" : "doc","_id" : "1","_score" : 0.2876821,"_source" : {"title" : "kubernetes docker","content" : "java spring python"}}]}

这样结果就符合我们的预期了

总结

使用dis max 查询可以达到 best_fields 匹配的效果,在某些细分的检索场景下效果更好,但单纯的 dis max 查询会导致忽略其他字段评分贡献,这种一刀切的机制并不是最优的策略,所以需要配合 tie_breaker 参数,来弱化非 best field 子句的评分贡献,从而达到最终的优化效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/42139.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 Redis 实现分布式限流

基于 Redis 实现分布式限流 一、 简介二、分布式限流1 数据结构1.1 Redis List1.2 Redis Set1.3 Redis Sorted Set 2 实现分布式限流3 实现原理分析 三、分布式限流算法1. 计数器算法2. 漏斗算法3. 令牌桶算法 四、分布式限流实战1. 单机限流实现2. 基于Redis Clusters的分布式…

常见程序搜索关键字转码

个别搜索类的网站因为用户恶意搜索出现误拦截情况,这类网站本身没有非法信息,只是因为把搜索关键字显示在网页中(如下图),可以参考下面方法对输出的关键字进行转码 DEDECMS程序 本文针对Dedecms程序进行搜索转码&…

优先级队列【C++】

文章目录 priority_queuepriority_queue 使用priority_queue的模拟实现向上调整算法向下调整算法pushpoptopsizeempty 仿函数完整代码 priority_queue 优先队列(priority_queue)也是队列的一种,priority_queue的接口是和queue的接口是相同的…

快速上手Vue开发:在项目中如何配置 tsconfig.json 文件?

文章目录 一、简介二、配置1、示例2、编译器选项列表 一、简介 tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项。 二、配置 1、示例 {"compilerOptions": {"baseUrl": ".","paths": {"/*": ["src/*&…

C#__基本特性和使用

// 特性(attribute): // 一种允许我们向程序集添加元数据的语言结构 // 用于保存程序结构信息的某种特殊类型的类 // 类似“批注”,用于解释说明 #define IsShowMessage // 宏定义,在开头定义&#xff0…

uni-app弹窗列表滚动, 弹框下面的内容也跟随滚动解决方案

滑动弹窗里的列表,弹框下面的内容也会跟着滑动,导致弹窗中的列表不能正常滚动 1.弹窗组件代码,需要在最外层的view中加入touchmove.stop.prevent"moveHandle",且弹窗中需要滚动的列表要使用scroll-view标签包裹起来&…

Python爬虫——requests_post请求

import requests import jsonurl https://fanyi.baidu.com/sugheaders {User-Agent: ,Cookie: }data {kw: hello }response requests.post(url, data, headersheaders)content response.textobj json.loads(content.encode(utf-8)) print(obj)总结: post请求…

五分钟搭建生鲜蔬果小程序

如今,随着移动互联网的快速发展,小程序已经成为众多企业和商家推广产品和服务的重要工具。而生鲜蔬果行业作为一个常见的消费领域,也开始逐渐转向小程序商城来进行销售和服务。那么,如何从零开始搭建一个生鲜蔬果小程序商城呢&…

Hlang--用Python写个解释器

文章目录 前言流程数学解释器结果封装数的操作运行时异常运行解释实现总结前言 没错今天提前来做这个东西,昨天晚上干这个玩意差不多干了两个多小时才搞定,导致凌晨2点才睡觉,最要命的是,写着写着突然想到有一道线代理解错了,一个晚上,做梦全是这两个东西。尤其是晚上效…

LeetCode150道面试经典题-- 快乐数(简单)

1.题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&am…

JVM——JVM参数指南

文章目录 1.概述2.堆内存相关2.1.显式指定堆内存–Xms和-Xmx2.2.显式新生代内存(Young Ceneration)2.3.显示指定永久代/元空间的大小 3.垃圾收集相关3.1.垃圾回收器3.2.GC记录 1.概述 在本篇文章中,你将掌握最常用的 JVM 参数配置。如果对于下面提到了一些概念比如…

Linux系统之安装my-mind思维导图工具

Linux系统之安装my-mind思维导图工具 一、my-mind介绍二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本3.3 检查端口占用情况 四、安装httpd4.1 检查本地yum仓库4.2 安装httpd4.3 关闭防火墙和selinux4.4 创建…

arcgis数据采集与拓扑检查

1、已准备好一张配准好的浙江省行政区划图,如下: 2、现在需要绘制湖州市县级行政区划。需要右击文件夹新建文件地理数据库,如下: 其余步骤均默认即可。 创建好县级要素数据集后,再新建要素类,命名为县。 为…

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,containsKey)五(117)

需求:前端根据后端的返回数据:画统计图; 1.动态获取地域数据以及数据中的平均值,按照平均值降序排序; 说明: X轴是动态的,有对应区域数据则展示; X轴 区域数据降序排序;…

03-第一个Spark程序WordCount

Scala版 1)创建项目 增加 Scala 插件 Spark 由 Scala 语言开发的,咱们当前使用的 Spark 版本为 3.2.0,默认采用的 Scala 编译版本为 2.13,所以后续开发时。我们依然采用这个版本。开发前请保证 IDEA 开发工具中含有 Scala 开发…

ebay灯串UL报告 UL588检测标准

季节性和装饰性照明用品即灯串以及配件都是便携式插头连接的临时性商品,最大额定输入电压为 120 伏。 由 ILAC ISO 17025 认证的实验室出具的检测报告,确认每件商品均已经过检测,符合下列要求: 季节性和装饰性照明用品(灯串&…

企业中商业智能BI,常见的工具和技术

商业智能(Business Intelligence,简称BI)数据可视化是通过使用图表、图形和其他可视化工具来呈现和解释商业数据的过程。它旨在帮助组织更好地理解和分析他们的数据,从而做出更明智的商业决策。 常见的商业智能数据可视化工具和技…

AtcoderABC222场

A - Four DigitsA - Four Digits 题目大意 给定一个整数N,其范围在0到9999之间(包含边界)。在将N转换为四位数的字符串后,输出它。如果N的位数不足四位,则在前面添加必要数量的零。 思路分析 可以使用输出流的格式设…

鼠标样式和指向

学习抖音&#xff1a; 渡一前端教科频道 图上指针跟着鼠标移动&#xff0c;并且改变方向 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><style>* {padding: 0;margin: 0;}.arrow {position: fixed;width: 3…

Spring Clould 消息队列 - RabbitMQ

视频地址&#xff1a;微服务&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; 初识MQ-同步通讯的优缺点&#xff08;P61&#xff0c;P62&#xff09; 同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&…