| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 23_深度探秘搜索技术_best fields策略的dis_max、tie_breaker参数以及multi_match语法 -> 正文阅读 |
|
[大数据]23_深度探秘搜索技术_best fields策略的dis_max、tie_breaker参数以及multi_match语法 |
目录 一、引入dis_max 实现best fields 的必要性 2、搜索title或content中包含java或solution的帖子 三、基于tie_breaker参数优化dis_max搜索效果 四、multi_match语法实现dis_max + tie_breaker 一、引入dis_max 实现best fields 的必要性当我们要对elsticsearch基于relevance scores(相关性分数)的搜索结果排序有较高的要求时,就需要基于dis_max实现best fields策略进行多字段搜索。以下将以示例的方式来说明使用dis_max 实现best fields 多字段搜索的必要性 1、使用bulk批量添加测试数据
2、搜索title或content中包含java或solution的帖子下面这个就是multi-field搜索,多字段搜索
3、结果分析
? 如上述图中所示,我们期望的是在同一个字段中,搜索的字段最相符合的出现在最前面,即doc5排在最前(doc5中的content字段匹配到了java 和solution)。结果是doc2排在了前面,和我们期望的不相符合。 那为什么会出现上述这个情况呢?这个就和elasticsearch 内部计算relevance scores 有关系。elasticsearch内部在计算每个document的relevance scores时。 遵循的计算规则是:每个query的分数相加,乘以matched query数量,除以总query数量。 接下来我们来验证以下doc2和doc5的分数是怎么的出来的。 对于doc2/doc5来说,搜索条件title和content都拥有自己的一个分数,即{ "match": { "title": "java solution" }}针对doc2/doc5是有一个分数的;{ "match": { "content": "java solution" }}针对doc2/doc5也是有一个分数的。两个搜索条件之间是互不干扰的。 假设doc2的title条件的得分是1.1,content条件的得分是1.2。由于是有两个搜索条件,故总query数量 = 2。doc2中只有title、content都匹配到了java,故matched query数量 = 2。按照计算公式(每个query的分数相加,乘以matched query数量,除以总query数量)doc2的最后得分为:(1.1 + 1.2)* 2 / 2 = 2.3。 假设doc5的title条件的得分是0(没有匹配中),content条件的得分是2。由于是有两个搜索条件,故总query数量 = 2。doc5中只有content匹配到了java 和 solution,故matched query数量 = 1。按照计算公式(每个query的分数相加,乘以matched query数量,除以总query数量)doc5的最后得分为:(0 + 2)* 1 / 2 = 1。 最后得出doc2的分数 = 2.3 > doc5的分数 = 1,则doc2排在了最强面。但是这样又和我们期望的结果不相同。我们所期望的是某一个field中匹配到了尽可能多的关键词,被排在前面;而不是尽可能多的field匹配到了少数的关键词,排在了前面。这时候我们就要引入elasticsearch 中的dis_max API了。 二、best fields策略(dis_max参数设置)best fields策略,就是说搜索到的结果应该是某一个field中匹配到了尽可能多的关键词,被排在前面;而不是尽可能多的field匹配到了少数的关键词,排在了前面,主要是通过dis_max 语法来进行控制的。 dis_max语法:直接取多个query中分数最高的那一个query的分数即可。
在上述示例中,针对于doc2 来说,title和content 都匹配到了java。假设doc2的title条件的得分是1.1,content条件的得分是1.2。 dis_max之后取最大分数为1.2。 针对doc5来说,假设doc5的title条件的得分是0(没有匹配中),content条件的得分是2。 dis_max之后取最大分数为2。 然后doc2的分数 = 1.2 < doc5的分数 = 2。所以doc5就可以排在更前面的地方,符合我们的需要。 三、基于tie_breaker参数优化dis_max搜索效果1、tie_breaker的使用原因可能在实际场景中出现的一个情况是这样的: (1)某个帖子doc1:title中包含java,content不包含java solution任何一个关键词 (2)某个帖子doc2:content中包含solution,title中不包含任何一个关键词 (3)某个帖子doc3:title中包含java,content中包含solution (4)最终搜索可能出来的结果是,doc1和doc2排在doc3的前面,而不是我们期望的doc3排在最前面 在上面这个例子中dis_max只是取分数最高的那个query的分数而已,完全不考虑其他query的分数。这种一刀切的做法,可能导致在有其他query的影响下,出现score不准确的情况。这时为了使用结果更准确,最好还是要考虑到其他query的影响。这个时候就需要使用tie_breaker 参数来优化dis_max的搜索效果 2、tie_breaker的使用方法使用tie_breaker将其他query的分数也考虑进去。tie_breaker参数的意义是将其他query的分数乘以tie_breaker,然后综合考虑后与最高分数的那个query的分数综合在一起进行计算,这样做除了取最高分以外还会考虑其他的query的分数。一般来说tie_breaker的值设置在在0~1之间,是个小数就行,没有固定的值。 示例:搜索title或content中包含java solution的帖子
四、multi_match语法实现dis_max + tie_breaker在dis_max 中,我们还可以设置minimum_should_match、boost等一系列的参数。
示例:搜索title或content中包含java solution的帖子,并设置title的搜索权重为2。
在上面的例子中,我们还可以进一步优化以及变种,可以使用multi_match进一步精简dsl语句,如下所示:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 11:41:57- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |