2023-08-08  阅读(319)
原文作者: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
阅读全文
  • 点赞