使用数千个字段设计选项

时间:2017-12-11 19:58:16

标签: elasticsearch elasticsearch-5

我正在尝试为"术语"的通用列表设计映射。它有一个标签和值:

terms = [
  { label: "Start Date", value: "2017/12/11" }, <- this is a date
  { label: "End Date", value: "2027/12/11" }, 
  { label: "Owner", value: "Monsters INC." }, <- this is text
  { label: "Fees", value: "1000$" } <- this is a numeric field
]

虽然所有文档将共享几个常见字段,但我有几个不同的文档模板,用户可以使用不同的数据类型向列表中添加自定义术语。

我需要使用一些布尔逻辑来查询文档,例如&#34;获取开始日期为去年且费用低于1000美元且所有者为&#34;怪物INC。&#34;

我有一个非常大的术语列表(数千个),还有几个可以由用户添加或由开发团队添加。

我已经探讨了这个问题的两种解决方案:

存储为嵌套对象:

映射看起来如此:

"terms":

                {
                    "type": "nested",
                    "properties": {
                        "label": { "type": "string" },
                        "value": { "type": "string" },
                        "source": { "type": "string" },
                        "page": { "type": "string" }
                    }
                }

优点:添加新术语时,无需重新制作索引,缩小映射

缺点:

查询更难,因为我们需要检查标签与值的关系。

由于所有值都是字符串,因此无法使用lt,gt

可能有可能实现LT,GT使用铸造但它似乎很慢(违背了ES的目的)

创建大型地图:

只需创建一个包含每个可能术语的大对象:

{
   "Start Date": { "type": "date" },
   "End Date": { "type": "date" },
   "Owner": { "type": "text" },
   "Fees": { "type": "integer" },
    ... add as many terms as needed
}

优点:查询变得简单,可以执行gt,lt,可以对每个字段应用任何所需的优化(如确切字段,关键字字段等)

缺点:ES不建议使用大的esparce映射,因为每个文档都共享相同的底层数据结构。

保持术语列表更新的更多工作

具有相同名称的术语如果具有不同的数据类型可能会发生冲突

ES提供的这种模式有没有解决方案? 任何帮助赞赏。

我们目前正在使用ES 5.5 目前词典中有1400个术语

1 个答案:

答案 0 :(得分:1)

假设您知道术语的类型以及索引和搜索的时间,您可以对名称中的值的类型进行编码,并使用带模式匹配的动态模板。您只需构建一个标签投影(&#34;开始日期&#34;)到具有编码类型的属性名称(&#34; start_date_date&#34;)并将标签写为字符串和动态类型值进入它,因此您可以将匹配模式(<p class="price text-center ng-binding" total-price=""> € 0.44 </p>)的所有内容映射到某个特定类型

编辑: Dynamic templates是Elasticsearch的一部分。通过这种方式,您可以为将在以下情况下应用的映射定义模板。字段名称与特定模式匹配。

*_date

此代码段将使用{"terms: { "dynamic_templates": [ "date_term": { "match_mapping_type": "string", "match": "*_date", "mapping": { "type": "date" } }, "numeric_term": { "match_mapping_type": "string", "match": "*_number", "mapping": { "type": "long" } } ] }} 的{​​{1}}类型和date start_date_date,如果您将两种情况下的值都提供为字符串(这就是long的用途。如果您将其作为double提供,Elasticsearch自己的动态映射(如果已启用)已经将它映射到double。