2023-08-08  阅读(0)
原文作者:Ressmix 原文地址:https://www.tpvlog.com/article/146

上一章,我对Elasticsearch中的整个相关度分数算法的核心思想和原理进行了讲解,包括TF/IDF,vector space model,boolean model等等。
本章,我们就来看看,实际在使用Elasticsearch的过程中,如何对相关度分数进行调优。综合来讲,主要有如下四种方法,我们一一来看下:

  • query-time boost
  • negative boost
  • constant_score
  • function_score

一、query-time boost

query-time boost就是利用boost增强某个query的权重,比如下面的查询有两个搜索条件,针对title字段的查询由于添加了boost参数,使其权重更大,所以title在匹配doc中分数占比会更大:

    GET /forum/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "title": {
                  "query": "java spark",
                  "boost": 2
                }
              }
            },
            {
              "match": {
                "content": "java spark"
              }
            }
          ]
        }
      }
    }

二、negative boost

negative boost,主要用于减少某些字段的权重,可以看成是query-time boost的反向参数。

比如我们有这样一个查询需求:搜索content字段中包含"java",但不包含spark的"document"。那么,可能会像下面这样构造查询请求:

    GET /forum/_search 
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "content": "java"
              }
            }
          ],
          "must_not": [
            {
              "match": {
                "content": "spark"
              }
            }
          ]
        }
      }
    }

但是有时候,我们不希望完全排除某个关键字,可能只是希望如果字段中包含某个关键字,就降低它的分数,比如上面的spark。

对于这种需求,可以使用negative_boost,包含了negative term的document,其分数会乘以negative boost

    GET /forum/_search 
    {
      "query": {
        "boosting": {
          "positive": {
            "match": {
              "content": "java"
            }
          },
          "negative": {
            "match": {
              "content": "spark"
            }
          },
          "negative_boost": 0.2
        }
      }
    }

三、constant_score

如果我们压根不需要相关度评分,就直接用constant_score加filter,这样所有的doc分数都是1,没有评分的概念:

    GET /forum/_search 
    {
      "query": {
        "bool": {
          "should": [
            {
              "constant_score": {
                "query": {
                  "match": {
                    "title": "java"
                  }
                }
              }
            },
            {
              "constant_score": {
                "query": {
                  "match": {
                    "title": "spark"
                  }
                }
              }
            }
          ]
        }
      }
    }

四、function_score

我们还可以使用function_score,自定义相关度分数的算法。

比如我们有这样一个需求:希望看某个帖子的人越多,那么该帖子的分数就越高,帖子浏览数可以定义为一个follower_num字段。那么可以像下面这样使用function_score

    GET /forum/_search
    {
      "query": {
        "function_score": {
          "query": {
            "multi_match": {
              "query": "java spark",
              "fields": ["tile", "content"]
            }
          },
          "field_value_factor": {
            "field": "follower_num",
            "modifier": "log1p",
            "factor": 0.5
          },
          "boost_mode": "sum",
          "max_boost": 2
        }
      }
    }

上述请求中:

  • log1p是一个函数,用于对字段分数进行修正:new_score = old_score * log(1 + factor * follower_num)
  • boost_mode,用于决定最终doc分数与指定字段的值如何计算:multiply,sum,min,max,replace;
  • max_boost,用于限制计算出来的分数不要超过max_boost指定的值。

五、总结

本章,我介绍了如何对相关度分数进行调优。综合来讲,主要有如下四种方法:

  • query-time boost
  • negative boost
  • constant_score
  • function_score

Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文