根据我们上面的讨论,在浏览了您发布的博客文章之后,我非常肯定在您的情况下,您根本不需要别名,并且路由密钥就足够了。同样,仅仅因为你有一个索引,如果你有很多索引,这将不再是真的!
您只需指定索引文档时要使用的路由键。在 ES 2.0 之前,您可以将该_routing
字段用于该目的,即使它在 ES 1.5 中已被弃用,但在您的情况下,它可以满足您的目的。
{
"customer" : {
"_routing" : {
"required" : true,
"path" : "customer_id" <----- the field you use as the routing key
},
"properties": { ... }
}
}
&routing=<customer_id>
然后,在搜索时,除了客户 ID 过滤器之外,您只需在搜索 URL 中指定(因为给定的分片可以为不同的客户托管文档)。您的搜索将直接转到由给定路由键标识的分片,因此,仅检索来自指定客户的数据。
为此使用过滤的别名不会带来任何好处,因为您在别名定义中包含的过滤器和路由键不会贡献任何额外的东西,因为检索到的文档已经被路由键“过滤”(某种程度)。这比尝试检测(在要索引的每个新文档上)是否存在别名并在不存在时创建它要容易得多。
更新:
现在,如果您绝对拥有/想要创建过滤别名,那么您提到的第一种方式将是更高效的方式:
- 首先索引您的日常数据
- 然后在您的字段上运行足够高的
terms
聚合(即高于字段的基数,在您的情况下约为 100),以确保您捕获所有唯一的客户 ID 以创建您的别名customer_id
size
- 遍历所有存储桶以检索所有唯一的客户 ID
- 在一个镜头中创建所有别名,每个镜头使用一个
action
customer_id
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" } }
}
},
...
]
}'
请注意,如果别名已经存在,您不必担心,整个命令不会失败并默默地忽略现有别名。
运行此命令后,您将拥有唯一索引上的所有别名,并使用过滤器和路由键正确配置。