带你读《Elastic Stack 实战手册》之74:——4.1.6.优化Elasticsearch中的打分(_score)(下)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 带你读《Elastic Stack 实战手册》之74:——4.1.6.优化Elasticsearch中的打分(_score)(下)

《Elastic Stack 实战手册》——四、应用实践——4.1 企业搜索应用场景 ——4.1.6.优化Elasticsearch中的打分(_score)(中) https://developer.aliyun.com/article/1226240



Boolean query

 

Boolean query 是较为常用的 bool 查询,可以将多个查询语句组合到一起,bool 查询有四个类型参数,must:表示文档必须满足的条件;filter:同 must 一样,文档必须满足条件,但是忽略相关性打分,查询条件不会对 _score 有影响;should:表示文档如果满足条件会加分,用 minimum_should_match 控制 should 条件中最少满足的个数;must_not:表示文档不能满足的条件,如果文档满足这里面的条件,则不会被搜出来。对于我们的 DSL,可能条件有很多,但是我们只要将需要相关性打分的条件放到 must 中,其他的放到 filter 中,这样既不会影响 _score 的计算,同时 Elasticsearch 对 filter 中部分条件语句有缓存,可以提升我们的查询效率。

POST _search
{
  "query": {
    "bool" : {  // 指定我们的查询为bool 查询
      "must" : {
        "term" : { "user.id" : "kimchy" }  
    // 文档的 user.id 字段必须等于kimchy
      },
      "filter": {
        "term" : { "tags" : "production" } 
    // 文档的 tags 字段必须有 production,这里 tags 为一个数组
      },
      "must_not" : {
        "range" : {
          "age" : { "gte" : 10, "lte" : 20 } 
      // 文档的 age 字段不可以在10到20范围内
        }
      },
      "should" : [
        { "term" : { "tags" : "env1" } }, 
    // 如果文档的 tags 字段中有env1,增加评分
     { "term" : { "tags" : "deployed" } } 
    // 如果文档的 tags 字段中有deployed,增加评分
      ],
      "minimum_should_match" : 1, // 表示 should 条件中满足一个就可以增加打分
      "boost" : 1.0
    }
  }
}

Boosting query

 

Boosting query 有三个参数,positive、negative、negative_boost,使用这个查询以后,会返回满足 positive 条件的文档,同时如果文档满足 negative 的条件,就会降低这个文档的相关性分数,降低的比例由 negative_boost 指定。计算方法是如果文档满足 negative 的条件,就会将 positive 中计算好的打分乘以 negative_boost。negative_boost 取值范围在0~1之间。

GET /_search
{
  "query": {
    "boosting": {  // 指定查询为 boosting 查询
      "positive": {
        "term": {
          "text": "apple"  // 查询 text 字段等于 apple 的文档
        }
      },
      "negative": {   // 满足该条件的文档将会降低打分
        "term": {
          "text": "pie tart fruit crumble tree"
        }
         },
      "negative_boost": 0.5
    }
  }
}

Disjunction max query

 

如果我们有多个条件,我们需要将条件中分数最高的作为相关性分数,我们就可以用这个查询语句,我们可以在 queries 中指定多个查询或者使用 multi_match。同时如果需要将除了最高分语句以外的其他语句也进行计算得分,使用 tie_breaker 指定这些语句的得分比例。


GET /_search
{
  "query": {
    "dis_max": {  // 表示这个查询是一个 Disjunction max query
      "queries": [ // 指定多个查询,取打分最高的
        { "term": { "title": "Quick pets" } },
        { "term": { "body": "Quick pets" } }
      ],
      "tie_breaker": 0.7
    }
  }
}
GET /_search
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "multi_match": {
           "query": "apple",
            "fields": ["name", "desc"] 
      // 也可以这样写,表示在多个字段中查询 apple, 优先取分数高的
          }
        }
        ]
    }
  }
}

 function_score query

 

这个查询主要用来修改查询返回的分数,例如在搜索商品时,需要考虑商品的受欢迎程度,增加店铺的热度;点外卖时需要考虑店铺的距离,好评率等。在使用 function_score 时,需要指定一个或者多个计算函数,通过这些函数来为查询返回的每个文档计算一个新的分数。首先,通过参数 score_mode 指定如何组合计算分数,有以下选项:

 

1、multiply:分数相乘(默认)

2、sum:分数相加

3、avg:分数是平均值

4、first:具有匹配filter条件的第一个函数被应用

5、max:使用最高分

6、min:使用最低分

 

使用参数 boost_mode 定义新计算的分数与查询的分数合并,有以下选项:

 

1、multiply:查询分数和新计算的分数相乘(默认)

2、replace:仅使用新计算的分数,查询分数将被忽略

3、sum:查询分数和新计算的分数相加

4、avg:查询分数和新计算的分数的平均值

5、max:查询分数和新计算的分数的最大值

6、min:查询分数和新计算的分数的最小值

然后就需要如何计算这个新的分数了,可以使用 script_score 指定一个脚本来计算分数,这里可以使用上面说的 Script Score query 中的脚本语句,script_score 函数部分不需要进行修改,可以直接拷贝到这里就可以运行;random_score 生成一个随机分数;field_value_factor 可以使用文档中的字段来影响得分,filed 指定要从文档中提取的字段,factor指定字段乘以的可选因子,modifier 指定对该字段的计算方法:log,log1p,log2p,ln,ln1p,ln2p,平方,sqrt 或 reciprocal,默认为无。如果我们需要我们文档的一些字段来影响打分,就可以用这个函数,具体如何使用,需要根据业务来定。


GET /_search
{
  "query": {
    "function_score": { // 定义一个 function_score query
      "field_value_factor": {
        "field": "my-int", // 需要计算的字段
        "factor": 1.2,
        "modifier": "sqrt", // 计算方式是取平方根
        "missing": 1
      }
    }
  }
}

限制文档的返回数量

 

在总文档数很多的情况下,可能一个 query 会返回成千上万的文档,如果我们想要在不改变 query 的前提下限制返回的数量,就需要用到另一个 search 参数:min_score,设置一个分数,匹配的文档如果 _score 低于这个分数,则相当于不满足条件,不返回。这个参数可以应用在这样的场景中:用户指定某一条件排序,比如说价格排序,可能 query 命中了很多文档,按照价格排序后会导致很多不是那么相关的文档排在前面,影响用户体验,如果我们在搜索之前,先拿到相关性符合我们预期的最后一篇文档的相关性分数,就可以在其他排序中指定min_score 为这个分数,这样不管怎么排序,出来的文档都是比较相关的。例如:

GET /_search
{
    "min_score": 0.5,  
  // 表示我们搜出来的文档需要满足打分大于等于0.5,不满足则不会被搜索出来
    "query" : {  // min_score 需要于下面定义好的查询计算好的得分去比较
        "term" : { "user" : "kimchy" }  
    }
}

小结

 

以上的方法都是使用 Elasticsearch 自带的参数和方法实现的,大部分的业务场景都可以用到,如果公司只有几个人来负责搜索模块,且没有专门的搜索算法工程师,我们可以考虑用

Elasticsearch 自带这些功能来满足我们的需求。如果需要排+精排,或者使用算法等来计算打分,那我们可以去实现一个打分插件来支持。本文只是讲了 Elasticsearch 中的一些基本功能,如何用好这些功能,可以参考官方的文档好好琢磨。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
3月前
|
JSON Prometheus Cloud Native
Grafana 系列 - 统一展示 -8-ElasticSearch 日志快速搜索仪表板
Grafana 系列 - 统一展示 -8-ElasticSearch 日志快速搜索仪表板
|
2天前
|
存储 缓存 搜索推荐
深入理解Elasticsearch倒排索引原理与优化策略
总之,Elasticsearch的倒排索引是其高效全文搜索的核心。为了提高性能和可伸缩性,Elasticsearch采用了多种优化策略,包括压缩、分片、合并、位集合和近实时搜索等。这些策略使Elasticsearch成为处理大规模文本数据的强大工具。
7 0
|
3天前
|
SQL 监控 搜索推荐
Elasticsearch 与 OpenSearch:开源搜索技术的演进与选择
Elasticsearch 与 OpenSearch:开源搜索技术的演进与选择
31 2
|
3天前
|
运维 架构师 搜索推荐
7 年+积累、 Elastic 创始人Shay Banon 等 15 位专家推荐的 Elasticsearch 8.X新书已上线...
7 年+积累、 Elastic 创始人Shay Banon 等 15 位专家推荐的 Elasticsearch 8.X新书已上线...
21 4
|
3天前
|
存储 数据处理 索引
Elasticsearch 8.X 小技巧:使用存储脚本优化数据索引与转换过程
Elasticsearch 8.X 小技巧:使用存储脚本优化数据索引与转换过程
29 6
|
3天前
|
运维 索引
Elasticsearch 写入优化探索:是什么影响了refresh 耗时?
Elasticsearch 写入优化探索:是什么影响了refresh 耗时?
21 7
|
3天前
|
运维 测试技术 数据处理
Elasticsearch 优化查询中获取字段内容的方式,性能提升5倍!
Elasticsearch 优化查询中获取字段内容的方式,性能提升5倍!
14 0
|
3天前
|
人工智能 程序员 开发者
Elasticsearch 中文社区的转型后,搜索人怎么破局?
Elasticsearch 中文社区的转型后,搜索人怎么破局?
10 0
|
3天前
|
监控 固态存储 安全
源码剖析:Elasticsearch 段合并调度及优化手段
源码剖析:Elasticsearch 段合并调度及优化手段
8 0
|
3天前
|
存储 机器学习/深度学习 API
高维向量搜索:在 Elasticsearch 8.X 中利用 dense_vector 的实战探索
高维向量搜索:在 Elasticsearch 8.X 中利用 dense_vector 的实战探索
16 0
高维向量搜索:在 Elasticsearch 8.X 中利用 dense_vector 的实战探索

相关产品

  • 检索分析服务 Elasticsearch版