我们计划使用此处提到的过滤别名 - https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html
我们的输入数据将成为一个流,其中每一行的流对应于我们想要存储在ES中的对象。
每个对象都包含一个'id',我们将其用于路由和过滤。
问题 - 我们如何以高效的方式创建别名和索引数据?
- 我们是否索引所有数据,跟踪所有唯一的'id',最后创建过滤后的别名?或者
- 对于每个对象,检查是否存在该“id”的别名;如果没有创建一个?
我倾向于第一种方法。与第二种方法相比,它是否可取且性能如何?
TIA。
答案 0 :(得分:1)
根据我们上面的讨论,在浏览了你发布的博客文章之后,我非常肯定在你的情况下你根本不需要别名,路由键就足够了。再说一遍,只因为你有一个索引,如果你有很多索引,那就再也不行了!
您只需指定索引文档时使用的路由键即可。在ES 2.0之前,您可以使用_routing
field来实现此目的,即使它已在ES 1.5中弃用,但在您的情况下它可以满足您的目的。
{
"customer" : {
"_routing" : {
"required" : true,
"path" : "customer_id" <----- the field you use as the routing key
},
"properties": { ... }
}
}
然后在搜索时,除了客户ID过滤器之外,您只需在搜索URL中指定&routing=<customer_id>
(因为给定的分片可以为不同的客户托管文档)。您的搜索将直接转到由给定路由键标识的分片,因此仅从指定客户检索数据。
使用过滤后的别名没有任何结果,因为您在别名定义中包含的过滤器和路由键不会有任何额外的贡献,因为检索到的文档已被路由键“过滤”(种类)。这比尝试检测(在每个要索引的新文档上)是否存在别名更容易,如果不存在则创建它。
更新:
现在,如果您绝对拥有/想要创建过滤后的别名,那么您提到的第一个更高效的方式就是:
terms
字段上运行customer_id
聚合,size
字段足够高(即高于字段的基数,在您的情况下大约为100)以确保您捕获所有唯一的客户ID以创建别名action
customer_id
在one shot中创建所有别名
醇>
curl -XPOST 'http://localhost:9200/_aliases' -d '{ "actions" : [ { "add" : { "index" : "customers", "alias" : "alias_cid1", "routing" : "cid1", "filter" : { "term" : { "customer_id" : "cid1" } } } }, { "add" : { "index" : "customers", "alias" : "alias_cid2", "routing" : "cid2", "filter" : { "term" : { "customer_id" : "cid2" } } } }, { "add" : { "index" : "customers", "alias" : "alias_cid3", "routing" : "cid3", "filter" : { "term" : { "customer_id" : "cid3" } } } }, ... ] }'
请注意,如果别名已经存在,您不必担心,整个命令不会失败并默默地忽略现有别名。
当此命令运行时,您将拥有唯一索引上的所有别名,并使用过滤器和路由键正确配置。