Elasticsearch:了解和解决文档更新后 Elasticsearch 分数的变化

这篇具有很好参考价值的文章主要介绍了Elasticsearch:了解和解决文档更新后 Elasticsearch 分数的变化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Elasticsearch:了解和解决文档更新后 Elasticsearch 分数的变化

问题

问卷中有如下这样的文档,开发者想通过 match query 搜索这些文档来使用分数。

POST sample-index-test/_doc/1
{
    "first_name": "James",
    "last_name" : "Osaka"
}

以下是对上述文档的示例查询:

GET sample-index-test/_explain/1
{
  "query": {
    "match": {
      "first_name": "James"
    }
  }
}

上述命令给出来的结果是:

{
  "_index": "sample-index-test",
  "_id": "1",
  "matched": true,
  "explanation": {
    "value": 0.2876821,
    "description": "weight(first_name:james in 0) [PerFieldSimilarity], result of:",
    "details": [
      {
        "value": 0.2876821,
        "description": "score(freq=1.0), computed as boost * idf * tf from:",
        "details": [
          {
            "value": 2.2,
            "description": "boost",
            "details": []
          },
          {
            "value": 0.2876821,
            "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": 1,
                "description": "N, total number of documents with field",
                "details": []
              }
            ]
          },
          {
            "value": 0.45454544,
            "description": "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
            "details": [
              {
                "value": 1,
                "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": 1,
                "description": "dl, length of field",
                "details": []
              },
              {
                "value": 1,
                "description": "avgdl, average length of field",
                "details": []
              }
            ]
          }
        ]
      }
    ]
  }
}

如你所知,Elasticsearch 根据相关性对文档进行评分。 在为该文档建立索引后,让我们现在搜索索引。我们目前只有一份关于该索引的文档。

GET sample-index-test/_search
{
  "query": {
    "match": {
      "first_name": "James"
    }
  }
}

搜索后,你将看到以下结果:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "sample-index-test",
        "_id": "1",
        "_score": 0.2876821,
        "_source": {
          "first_name": "James",
          "last_name": "Osaka"
        }
      }
    ]
  }
}

我想提请你注意结果的 _score 字段。 如你所见,我们文档的 _score 值为 0.2876821 。 例如,当你多次更新文档时,假设我们使用以下请求更新了记录 10 次:

POST sample-index-test/_update/1
{
  "script" : "ctx._source.first_name = 'James'; ctx._source.last_name = 'Cena';"
}

或者 

POST sample-index-test/_doc/1
{
    "first_name": "James",
    "last_name" : "Cena"
}

不会有任何添加到索引中。 我们又有了一份文件,没有了。 我们刚刚更新了文档的 last_name 字段。 让我们再次进行精确搜索并尝试查看结果:

GET sample-index-test/_search
{
  "query": {
    "match": {
      "first_name": "James"
    }
  }
}

上面的命令显示的结果是:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.046520013,
    "hits": [
      {
        "_index": "sample-index-test",
        "_id": "1",
        "_score": 0.046520013,
        "_source": {
          "first_name": "James",
          "last_name": "Cena"
        }
      }
    ]
  }
}

正如你在此处看到的,分数发生了变化。 该文档的分数现在为 0.046520013 。 但根据 TF/IDF 计算,我们需要看到与我们的第一个搜索响应相同的分数。 因为当我们将它与文档的第一个状态进行比较时,没有任何变化。 即使我没有更改 first name 字段,我也只是更改了 last_name 字段并继续搜索 first_name 。 让我们对 _explain 端点进行更多挖掘。

GET sample-index-test/_explain/1
{
  "query": {
    "match": {
      "first_name": "James"
    }
  }
}

Explain API 端点将为查询和特定文档计算得分解释。 上述请求的结果如下所示:

{
  "_index": "sample-index-test",
  "_id": "1",
  "matched": true,
  "explanation": {
    "value": 0.046520013,
    "description": "weight(first_name:james in 0) [PerFieldSimilarity], result of:",
    "details": [
      {
        "value": 0.046520013,
        "description": "score(freq=1.0), computed as boost * idf * tf from:",
        "details": [
          {
            "value": 2.2,
            "description": "boost",
            "details": []
          },
          {
            "value": 0.046520017,
            "description": "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
            "details": [
              {
                "value": 10,
                "description": "n, number of documents containing term",
                "details": []
              },
              {
                "value": 10,
                "description": "N, total number of documents with field",
                "details": []
              }
            ]
          },
          {
            "value": 0.45454544,
            "description": "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
            "details": [
              {
                "value": 1,
                "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": 1,
                "description": "dl, length of field",
                "details": []
              },
              {
                "value": 1,
                "description": "avgdl, average length of field",
                "details": []
              }
            ]
          }
        ]
      }
    ]
  }
}

去掉一些对我们来说是可选的部分。 现在让我们关注 IDF 计算。 如你所知,反向文档频率(Inverse Document Frequency)查看一个词在语料库中的常见(或不常见)程度。 这意味着我们将使用索引中的文档数来计算 IDF。有关 IDF 的更多知识,请阅读文章 “Elasticsearch:分布式计分”。

idf, computed as log(1 + (N - n + 0.5) / (n + 0.5))

正如你在上面看到的,我们使用的是文档总数,但问题是我们在索引中有一个文档,但它显示的是 10。

              {
                "value": 10,
                "description": "n, number of documents containing term",
                "details": []
              },
              {
                "value": 10,
                "description": "N, total number of documents with field",
                "details": []
              }

因此,如果你使用此分数来计算其他服务的内容,这就是问题所在。

为什么会这样?

Elasticsearch 使用 Lucene 并将所有文档存储在段中。 段(segment)是不可变的,文档更新操作有两步过程。 更新文档时,将创建一个新文档,并将旧文档标记为已删除。 所以,当你在 Elasticsearch 索引中创建第一个文档时,Elasticsearch 会将它保存在一个段中,并且只有一个文档。 然后你更新同一个文档 10 次; 在任何更新操作中,Elasticsearch 都会在一个段中创建另一个文档,并将最旧的文档标记为已删除。 但是当你搜索索引时,你会从段中找到最新的文档状态。 暂时删除的文档数量为10。你会再次搜索到文档的最新状态,但 Elasticsearch 会继续在内部统计它们以进行IDF 计算。 因此,每次更新后,“the number of documents with field” 和 “number of documents containing term” 都会发生变化。

解决方案

如你所知,如果你知道什么是段,这个问题会在一段时间后自行解决。 所以,如果你想自己做这件事而不等待,你需要使用 _forcemerge。 我需要在这里放一个来自 Elasticsearch 文档的解释。在我们稍微等一段时间后,我们再去搜索,我们将会看到最终的分数和我们刚开始搜索的结果是一样的。

合并通过将其中的一些合并在一起来减少每个分片中的段数,并且还释放已删除文档所使用的空间。 合并通常会自动发生,但有时手动触发合并很有用。
我们建议只强制合并只读索引(意味着索引不再接收写入)。

为了对我们的索引执行 _forcemerge,我们使用了以下请求:

POST sample-index-test/_forcemerge

根据你的索引大小,此请求可能需要一些时间,你可以通过在 Kibana 上执行以下请求来完成任务:

GET _tasks?actions=*forcemerge*&detailed

另一种方法就是等待。 Elasticsearch 还有一个调度程序和合并策略来自动合并段。 在使用强制合并之前,我建议仔细阅读相关的官方文档。

最后,还有一个索引生命周期操作,用于使用策略执行强制合并操作。 根据你的逻辑,你可以使用不同的解决方案来获得更好的搜索评分结果。文章来源地址https://www.toymoban.com/news/detail-422388.html

到了这里,关于Elasticsearch:了解和解决文档更新后 Elasticsearch 分数的变化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决Vue数组数据变化了,赋值后视图没更新的问题

    最近遇到一个问题,表格数据变化了,直接赋值后视图没更新,打印表格数据发现是最新的数据,这主要是因为,Vue.js 不能检测到对象属性的添加或删除。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的。

    2024年02月02日
    浏览(39)
  • SpringCloud(十)——ElasticSearch简单了解(二)DSL查询语句及RestClient查询文档

    查询所有 :查询出所有数据,一般测试用。例如: match_all 全文检索查询 :利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如: match_query multi_match_query 精确查询 :根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如: ids range

    2024年02月10日
    浏览(65)
  • Elasticsearch:Explain API - 如何计算分数

      你想了解你的文档为何获得该分数吗? 让我们通过一组示例文档来了解 Explain API。 就我而言,我将使用一小部分电影名言。 在网址 https://en.wikipedia.org/wiki/Okapi_BM25 你可以找到 Elasticsearch 中默认的评分算法。 boost — 常数 2.2 = (k1 + 1),忽略,与排序无关 freq — 该术语在字段

    2024年02月11日
    浏览(31)
  • ElasticSearch第十一讲 ES检索评分score以及分数计算逻辑

    relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度。Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法 Term frequency:搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,就越相关

    2023年04月23日
    浏览(40)
  • 【OTFS与信号处理:论文阅读1】:考虑分数多普勒的OTFS系统有效信道估计(已更新)

    2023.06.05 最近在研究OTFS考虑分数多普勒时信道估计与信号检测相关问题,最近精读了一篇论文,并针对论文中部分公式进行推导,故记录一下学习过程。 论文题目: Efficient Channel Estimation for OTFS Systems in the Presence of Fractional Doppler 论文地址: https://ieeexplore.ieee.org/document/10118

    2024年02月11日
    浏览(54)
  • 我的第一个项目(十二) :分数和生命值的更新(后端增删查改的"改")

    好家伙,写后端,这多是一件美逝. 关于这个项目的代码前面的博客有写  我的第一个独立项目 - 随笔分类 - 养肥胖虎 - 博客园 (cnblogs.com)   现在,我们登陆进去了,我开始和敌人战斗,诶,打到一百分了,我现在要把这个分数保存起来      随便写一个测试样例    (确实是非常朴实无

    2024年02月01日
    浏览(40)
  • ElasticSearch - DSL查询文档语法,以及深度分页问题、解决方案

    目录 一、DSL 查询文档语法 前言 1.1、DSL Query 基本语法 1.2、全文检索查询 1.2.1、match 查询 1.2.2、multi_match 1.3、精确查询 1.3.1、term 查询 1.3.2、range 查询 1.4、地理查询 1.4.1、geo_bounding_box 1.4.2、geo_distance 1.5、复合查询 1.5.1、相关性算分 1.5.2、function_score 1.5.3、boolean query 1.6、搜索

    2024年02月07日
    浏览(51)
  • Elasticsearch 8.X 分词插件版本更新不及时解决方案

    球友在 ElasticSearch 版本选型问题中提及:如果要使用ik插件,是不是就使用目前最新的IK对应elasticsearch的版本“8.8.2”? 如果要使用最新es版本,而IK没有对应的,老师有推荐的其他类似插件吗?谢谢!——问题来源:https://t.zsxq.com/13YX8fFQy IK Analyzer 描述:基于词典的中文分词

    2024年02月07日
    浏览(59)
  • 【OTFS与信号处理:论文阅读1】:考虑分数多普勒的OTFS系统有效信道估计(24.01.16更新)

    2023.06.05 最近在研究OTFS考虑分数多普勒时信道估计与信号检测相关问题,最近精读了一篇论文,并针对论文中部分公式进行推导,故记录一下学习过程。 论文题目: Efficient Channel Estimation for OTFS Systems in the Presence of Fractional Doppler 论文地址: https://ieeexplore.ieee.org/document/10118

    2024年01月17日
    浏览(51)
  • WPF绑定单变量Binding和绑定多变量MultiBinding 字符串格式化 UI绑定数据,数据变化自动更新UI,UI变化自动更新数据

    UI绑定数据,数据变化自动更新UI,UI变化自动更新数据。 支持多设备,同时下载。 在WPF (Windows Presentation Foundation) 中,您可以使用数据绑定来将变量绑定到界面元素。这允许您在界面上显示变量的值,并使这些值能够自动更新,而不需要手动更新界面。以下是如何绑定变量到

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包