我有一个用例,其中我有一组预定义字段,并且还需要支持向 ElasticSearch 添加动态字段,并对其进行一些基本搜索。我可以使用动态模板映射来实现这一点。不过,添加此类动态场的频率相当高。
考虑 Event 类型的 ES 文档:
{
"name":"Youth Conference",
"venue":"Ahmedabad",
"date":"10/01/2015",
"organizer":"Invincible",
"extensions":{
"about": {
"vision":"Visualizes the image of an ideal Country. ",
"mission":"Encapsulates the gravity of the top reformative solutions for betterment of Country."
}
// Any thing can go here..
}
}
在上面的示例中,每个事件文档可能有任何未知/新字段。因此,对于引入的每个这样的新动态字段,ES 将更新type的映射。我关心的是在现有类型中添加新字段映射的成本是多少?
我计划通过引入另一个type(例如EventExtensions)并使用父/子关系将其映射到Event类型,将所有动态映射(在extensions内)从Event类型中分离出来。我相信这可能会限制频繁向类型添加动态字段的成本(如果有)。然而,据我所知,使用父/子关系将需要更多的内存。
这里首先要记住的是,字段是每个索引而不是每个类型。 因此,无论您添加新字段,它都会在同一个索引中创建。无论是另一种类型,还是作为父母或孩子。 因此,将新字段解耦到另一种类型但相同的索引不会做出任何改变。
添加第二个字段并不是那么昂贵的事情。我认识一些人,他们使用 1000 个字段并且擅长使用它。话虽如此,字段编号上应该有一个选项卡,这样就不会出现疯狂的数字。
这里我们有多种方法来解决问题
我们假设新的字段数据不需要完全可搜索。在这种情况下,您可以将整个 JSON 反序列化为字符串并将其添加到字段中。另请确保该字段未建立索引。这样您就可以根据其他字段进行搜索,然后在检索文档时获取反序列化的信息。
假设新字段如下所示
{
"newInfo1" : "log Of Info",
"newInfo2" : "A lot more info"
}
代替这个,你可以使用
{
"newInfo" : [
{
"fieldName" : "newInfo1",
"fieldValue" : "log Of Info"
},
{
"fieldName" : "newInfo2",
"fieldValue" : "A lot more info"
}
]
}
这样,字段就不会增加。但是,要进行字段级别的特定搜索,例如给我所有 filename 为 newInfo2 且其中包含单词 more 的文档,您将需要创建 newInfo 字段嵌套。
希望这有帮助。