我试图为具有标签和价值的通用“术语”列表设计一个映射,如下所示:
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
]虽然所有文档都将共享几个公共字段,但我有几个不同的文档模板,用户可以使用不同的数据类型向列表中添加自定义术语。
我需要使用一些布尔逻辑来查询文档,比如“获取那些文档,这些文档的开始日期是去年,费用小于1000美元,而所有者是"monster。”。
我有一个相当大的术语列表(千),更多的术语可以由用户添加或由开发团队添加。
我探讨了两种解决这个问题的办法:
作为嵌套对象存储的:
映射看起来是这样的:
"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个术语
发布于 2017-12-11 23:09:48
假设您知道术语的类型,并且在索引和搜索时,您可以在名称中对值的类型进行编码,并使用带有模式匹配的动态模板。您只需将标签(“开始日期”)投影到带有编码类型("start_date_date")的属性名称,并将标签作为字符串和动态类型值写入其中,这样就可以将匹配模式(*_date)的所有内容映射到特定类型。
编辑:动态模板是Elasticsearch的一部分。这样,您就可以为映射定义一个模板,例如,当字段名匹配某一模式时,该模板将被应用。
{"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"
}
}
]
}}如果在这两种情况下都以字符串的形式提供date类型(这就是match_mapping_type的作用),那么这个片段将使用start_date_date的long类型和start_date_number的long类型。如果您将其作为double提供,Elasticsearch自己的动态映射(如果启用的话)将已经负责将其映射到double。
https://stackoverflow.com/questions/47760474
复制相似问题