我正在尝试为"术语"的通用列表设计映射。它有一个标签和值:
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个术语
答案 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。