2017-04-07 115 views
1

我想存储弹性搜索产品 每个产品都有一些字段(描述,数量,价格,名称)。但每一天的价格和数量都可能发生变化。历史弹性搜索文档建模

我怎么能这个存储弹性的搜索,这样我就可以搜索所有过去价格的任何产品吗?

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

回答

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作为重要档案的主存储。只有在偶然的数据丢失的情况下才能做到这一点。

0

首先你不应该用新的数量/价格更新现有的文件。

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

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