带你读《Elastic Stack 实战手册》之19:——3.4.2.4.分布式计分(下)

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

《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.4.分布式计分(中) https://developer.aliyun.com/article/1230902


预统计阶段:

 

1、Elasticsearch 在收到客户端搜索请求后,会由协调节点进行一次预统计工作,即先向所有相关 Shard 搜集统计信息

 

Query 阶段:

 

1、由协调节点整合所有统计信息,将全局的统计信息连同请求一起分发到对应索引的每个

Shard 上。

2、每个 Shard 的 Lucene 实例,基于全局的 TF/IDF 统计信息,独立完成 Shard 内的索引匹配和打分(基于上述公式),并根据打分结果,完成单个 Shard 内的排序、分页。

3、每个 Shard 将排序分页后的结果集的元数据(文档 ID 和分数,不包含具体的文档内容)返回给协调节点。

4、协调节点完成整体的汇总、排序以及分页,筛选出最终确认返回的搜索结果。

 

Fetch 阶段:

 

1、协调节点根据筛选结果去对应 shard 拉取完整的文档数据

2、整合最终的结果返回给用户客户端

 

综上可见,Elasticsearch 在分布式打分上做了权衡,如果要考虑绝对的精确性,那么需要牺牲一些性能来换取全局的统计信息。

 

让我们来看下如何切换到 DFS_QUERY_THEN_FETCH,只需在接口 URL 加上search_type=dfs_query_then_fetch


GET /my-index-000001/_search?search_type=dfs_query_then_fetch
{
  "query": {
    "query_string": {
      "query": "三国演义"
    }
  }
}

可以看到,通过这种方式返回的结果又恢复了正常:


{
  "took" : 9,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 3.7694218,
    "hits" : [
      {
        "_index" : "my-index-000001",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 3.7694218,
        "_source" : {
          "title" : "三国演义",
          "date" : "2021-05-03",
          "content" : "三国时代,群雄逐鹿..."
        }
      },
      {
        "_index" : "my-index-000001",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.1795839,
        "_source" : {
    375         >   三、产品能力
          "title" : "三国志",
          "date" : "2021-05-01",
          "content" : "国别体史书"
        }
      },
      {
        "_index" : "my-index-000001",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.8715688,
        "_source" : {
          "title" : "易中天品三国",
          "date" : "2021-05-03",
          "content" : "草船借箭、空城计..."
        }
      }
    ]
  }
}

三国演义”的文档仍排在第一,分数( _score )变成了 3.7694218,其次是“三国志”,分数是1.1795839,最后是“易中天品三国”,分数是0.8715688,其余没有匹配的文档同样没有出现。

 

另外,根据返回的 took 数据,可以看到耗时较 query_then_fetch 的方式有略增加,所以这种方式对性能会有折损,在生产环境中建议谨慎使用。

 

查看得分逻辑

 

为了在实际开发中了解得分逻辑,从而优化我们的查询条件或索引工作,我们需要关注例如“易中天品三国”为什么分数是 0.8715688,而不是 3.7694218。


 

我们可以通过在查询中增加 explain 来查看得分的说明信息。


GET /my-index-000001/_search?search_type=dfs_query_then_fetch
{
  "query": {
    "query_string": {
      "query": "三国演义"
    }
  },
  "explain": true
}


通过增加 "explain": true,我们可以看到返回的结果集里增加了大量 _explanation 信息:


{
  "took" : 21,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 3.7694218,
    "hits" : [
      {
        "_shard" : "[my-index-000001][0]",
        "_node" : "ydZx8i8HQBe69T4vbYm30g",
        "_index" : "my-index-000001",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 3.7694218,
        "_source" : {
          "title" : "三国演义",
          "date" : "2021-05-03",
          "content" : "三国时代,群雄逐鹿..."
        },
        "_explanation" : {
          "value" : 3.7694218,
          "description" : "max of:",
          "details" : [
            {
              "value" : 3.7694218,
              "description" : "sum of:",
              "details" : [
                {
                  "value" : 0.52763593,
                  "description" : "weight(title:三 in 0) [PerFieldSimilarity], result of:",
                  "details" : [
                    {
                      "value" : 0.52763593,
                      "description" : "score(freq=1.0), computed as boost * idf * tf from:",
                      "details" : [
                        {
                          "value" : 2.2,
                          "description" : "boost",
                          "details" : [ ]
                        },
                        {
                          "value" : 0.5389965,
                          "description" : "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
                          "details" : [
                            {
                              "value" : 3,
                              "description" : "n, number of documents containing term",
                              "details" : [ ]
                            },
                            {
                              "value" : 5,
                              "description" : "N, total number of documents with field",
                              "details" : [ ]
                            }
                          ]
                        },
                        {
                          "value" : 0.4449649,
                          "description" : "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
                          "details" : [
                            {
                              "value" : 1.0,
                              "description" : "freq, occurrences of term within document",
                              "details" : [ ]
                            },
                            {
                              "value" : 1.2,
                              "description" : "k1, term saturation parameter",
                              "details" : [ ]
                            },
                            {
                              "value" : 0.75,
                              "description" : "b, length normalization parameter",
                              "details" : [ ]
                            },
                            {
                              "value" : 4.0,
                              "description" : "dl, length of field",
                              "details" : [ ]
                            },
                            {
                              "value" : 3.8,
                              "description" : "avgdl, average length of field",
                              "details" : [ ]
                            }
                          ]
                        }
                      ]
                    }
                  ]
                },
                {
                  "value" : 1.357075,
                  "description" : "weight(title:演 in 0) [PerFieldSimilarity], result of:",
                  "details" : [
                    {
                      "value" : 1.357075,
                      "description" : "score(freq=1.0), computed as boost * idf * tf from:",
                      "details" : [
                        {
                          "value" : 2.2,
                          "description" : "boost",
                          "details" : [ ]
                        },
                        {
                          "value" : 1.3862944,
                          "description" : "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
                          "details" : [
                            {
                              "value" : 1,
                              "description" : "n, number of documents containing term",
                              "details" : [ ]
                            },
                            {
                              "value" : 5,
                              "description" : "N, total number of documents with field",
                              "details" : [ ]
                            }
                          ]
                        },
                        {
                          "value" : 0.4449649,
                          "description" : "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
                          "details" : [
                            {
                              "value" : 1.0,
                              "description" : "freq, occurrences of term within document",
                              "details" : [ ]
                            },
                            {
                              "value" : 1.2,
                              "description" : "k1, term saturation parameter",
                              "details" : [ ]
                            },
                            {
                              "value" : 0.75,
                              "description" : "b, length normalization parameter",
                              "details" : [ ]
                            },
                            {
                              "value" : 4.0,
                              "description" : "dl, length of field",
                              "details" : [ ]
                            },
                            {
                              "value" : 3.8,
                              "description" : "avgdl, average length of field",
                              "details" : [ ]
                            }
                          ]
                        }
                      ]
                    }
                  ]
                },
                ...
              ]
            },
            ...
          ]
        }
      },
     ...
    ]
  }
}

通过分析 description 和 details 中信息的描述,我们可以进一步深挖 Elasticsearch 的打分逻辑和我们查询出来的每个文档的得分详情。

 

创作人简介

赵震一,程序员,好奇技淫巧,关注大数据与分布式计算。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2天前
|
运维 关系型数据库 分布式数据库
PolarDB产品使用合集之在选择分布式数据库时,主要考虑是什么
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
2天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能平台PAI产品使用合集之如何在CPU服务器上使用PAIEasyRec进行分布式训练
阿里云人工智能平台PAI是一个功能强大、易于使用的AI开发平台,旨在降低AI开发门槛,加速创新,助力企业和开发者高效构建、部署和管理人工智能应用。其中包含了一系列相互协同的产品与服务,共同构成一个完整的人工智能开发与应用生态系统。以下是对PAI产品使用合集的概述,涵盖数据处理、模型开发、训练加速、模型部署及管理等多个环节。
|
2月前
|
SQL 关系型数据库 MySQL
Flink CDC产品常见问题之读分布式mysql报连接超时如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
3月前
|
存储 监控 Windows
ABB 分布式控制系统 DCS紧凑型产品套件 紧凑型HMI
ABB 分布式控制系统 DCS紧凑型产品套件 紧凑型HMI
ABB 分布式控制系统 DCS紧凑型产品套件 紧凑型HMI
|
4月前
|
数据库 OceanBase
OceanBase数据库是一个分布式集群产品,在部署时对硬件资源有特定的需求
OceanBase数据库是一个分布式集群产品,在部署时对硬件资源有特定的需求【1月更文挑战第12天】【1月更文挑战第56篇】
29 2
|
6月前
|
Dubbo 中间件 应用服务中间件
Seata:打造行业首个分布式事务产品
Seata:打造行业首个分布式事务产品
|
10月前
|
存储 Cloud Native 关系型数据库
阿里云最新产品手册——阿里云核心产品——云原生关系型数据库PolarDB——共享分布式存储
阿里云最新产品手册——阿里云核心产品——云原生关系型数据库PolarDB——共享分布式存储自制脑图
229 2
|
11月前
|
容器
阿里云最新产品手册——阿里云核心产品——分布式云容器平台ACK One——阿里云容器服务ACK Anywhere家族产品
阿里云最新产品手册——阿里云核心产品——分布式云容器平台ACK One——阿里云容器服务ACK Anywhere家族产品自制脑图
100 1
|
11月前
|
人工智能 Cloud Native 容器
阿里云最新产品手册——阿里云核心产品——分布式云容器平台ACK One——ACK云原生AI套件
阿里云最新产品手册——阿里云核心产品——分布式云容器平台ACK One——ACK云原生AI套件自制脑图
261 1
|
11月前
|
容器
阿里云最新产品手册——阿里云核心产品——分布式云容器平台ACK One——服务关联角色
阿里云最新产品手册——阿里云核心产品——分布式云容器平台ACK One——服务关联角色自制脑图
85 1