首页 文章

弹性搜索文档建模历史记录

提问于
浏览
1

我想在弹性搜索中存储产品每个产品都有一些字段(描述,数量,价格,名称) . 但每天价格和数量都可能发生变化 .

如何将其存储在弹性搜索中,以便我能够搜索所有过去价格的产品?

我是否应该有一个当前值字段的文档和另一个将产品文档作为父文档的文档,并且会有一些日常任务在数组中添加日期和更改的值?

2 回答

  • 0

    不幸的是,在ElasticSearch中没有内置的方法来处理版本控制 . built-in versioning不是为检索以前的版本而设计的 . 您需要在应用程序层控制版本控制 .

    我们最终选择做的是存储文档的所有旧副本,如下所示:

    {
      "unversioned_prop1": "prop1",
      "unversioned_prop2": "prop2",
      ...
      "versions": [
        {
          "version": "version_x",
          "version_metadata": { ... }
          "document": {
            "versioned_prop3": "prop3",
            "versioned_prop4": "prop4"
            ...
          }
        },
        { "version": "version_y", "document": { ... versioned props ... } },
        ...
      ]
      "current": { ... current versioned props ... }
    }
    

    Unversioned Properties

    将非版本化属性置于数组之外是有用的,因为您可能希望更新文档的所有版本的某些属性 . 此外,它确保搜索权重的行为可预测 .

    它的缺点是要求我们在应用程序层中将一些信息接合在一起 .

    Current Version

    将当前版本分解为单独的属性允许您使用search filtering仅返回文档的最新版本 .

    Version metadata

    这包括您可能要搜索的任何版本控制信息,例如日期 .

    Search

    您可以像子属性一样轻松搜索版本化属性 . 所以搜索最终看起来像这样:

    ...
    {
      "match": {"versions.document.versioned_prop": "query string"
    }
    

    这将搜索文档的所有版本,如果匹配则返回组合文档 .

    Updates

    当我们需要创建新版本时,您可以使用partial update插入新文档并更新当前文档 .

    Alternative

    这种方法的主要缺点是您无法根据版本内部的内容轻松过滤掉某些搜索结果 - 您可能希望在应用程序端过滤它们 .

    如果您需要您的文档独立运作,您可能需要单独索引它们 . 为此,您可以在所有版本中包含“集合ID” . 集合ID对于文档是唯一的,并且在所有版本中共享 .

    收集ID方法最终出现了太多问题,我们采用了上述方法,并取得了更高的成功 .


    作为旁注,我使用ElasticSearch作为重要记录的主存储 . 只有在您偶尔会遇到数据丢失的情况下才能这样做 .

  • 0

    首先,您不应该使用新的数量/价格更新现有文档 .

    我会建议每当数量/价格发生变化时,插入新文档 . 会有重复的字段,但您可以在文档中的给定日期获得有关该产品的所有信息 .

    您还可以检索该产品的所有文档,它将具有自己的值(价格).Data将在此建模中重复,但我不认为这是一个问题 .

相关问题