IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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 的必要性

1、使用bulk批量添加测试数据

2、搜索title或content中包含java或solution的帖子

3、结果分析

二、best fields策略(dis_max参数设置)

三、基于tie_breaker参数优化dis_max搜索效果

1、tie_breaker的使用原因

2、tie_breaker的使用方法

四、multi_match语法实现dis_max + tie_breaker


一、引入dis_max 实现best fields 的必要性

当我们要对elsticsearch基于relevance scores(相关性分数)的搜索结果排序有较高的要求时,就需要基于dis_max实现best fields策略进行多字段搜索。以下将以示例的方式来说明使用dis_max 实现best fields 多字段搜索的必要性

1、使用bulk批量添加测试数据

POST article/_bulk
{"create":{"_id":"1"}}
{"title":"this is java and elasticsearch blog","content":"i like to write best elasticsearch article"}
{"create":{"_id":"2"}}
{"title":"this is java blog","content":"i think java is the best programming language"}
{"create":{"_id":"3"}}
{"title":"this is elasticsearch blog","content":"i am only an elasticsearch beginner"}
{"create":{"_id":"4"}}
{"title":"this is java, elasticsearch, hadoop blog","content":"elasticsearch and hadoop are all very good solution, i am a beginner"}
{"create":{"_id":"5"}}
{"title":"this is spark blog","content":"spark is best big data solution based on scala ,an programming language similar to java"}

2、搜索title或content中包含java或solution的帖子

下面这个就是multi-field搜索,多字段搜索

GET article/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "java solution"
          }
        },
        {
          "match": {
            "content": "java solution"
          }
        }
      ]
    }
  }
}

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的分数即可。

GET article/_search
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match": {
            "title": "java solution"
          }
        },
        {
          "match": {
            "content": "java solution"
          }
        }
      ]
    }
  }
}

在上述示例中,针对于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的帖子

GET article/_search
{
  "query": {
    "dis_max": {
      "tie_breaker": 0.7,
      "boost": 1.2,
      "queries": [
        {
          "match": {
            "title": "java solution"
          }
        },
        {
          "match": {
            "content": "java solution"
          }
        }
      ]
    }
  }
}

四、multi_match语法实现dis_max + tie_breaker

在dis_max 中,我们还可以设置minimum_should_match、boost等一系列的参数。

  • minimum_should_match:主要是用来去长尾的。长尾指的是比如你搜索5个关键词,但是很多结果是只匹配1个关键词的,其实跟你想要的结果相差甚远,这些结果就是长尾。minimum_should_match就是控制搜索结果的精准度,只有匹配一定数量的关键词的数据才能返回
  • boost:可以将某个搜索条件的权重加大。

示例:搜索title或content中包含java solution的帖子,并设置title的搜索权重为2。

GET article/_search
{
  "query": {
    "dis_max": {
      "tie_breaker": 0.7,
      "boost": 1.2,
      "queries": [
        {
          "match": {
            "title": {
              "query": "java solution",
              "boost": 2, 
              "minimum_should_match": "50%"
            }
          }
        },
        {
          "match": {
            "content": {
              "query": "java solution",
              "minimum_should_match": "50%"
            }
          }
        }
      ]
    }
  }
}

在上面的例子中,我们还可以进一步优化以及变种,可以使用multi_match进一步精简dsl语句,如下所示:

GET article/_search
{
  "query": {
    "multi_match": {
      "query": "java solution",
      "fields": [
        "title^2",
        "content"
      ],
      "type": "best_fields",
      "tie_breaker": 0.7,
      "minimum_should_match": "50%"
    }
  }
}

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:37:32  更:2022-02-26 11:38:37 
 
开发: 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-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码