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

时间:2017-04-07 20:46:13

标签: elasticsearch

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

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

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

2 个答案:

答案 0 :(得分: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 ... }
}

无版权属性

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

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

当前版本

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

版本元数据

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

搜索

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

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

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

<强>更新

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

<强>替代

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

如果您需要您的文档独立行事,您可能需要独立编制索引。为此,您可以在所有版本中包含“集合ID”。集合ID对于文档是唯一的,并且在所有版本中共享。

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

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

答案 1 :(得分:0)

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

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

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