ElasticSearch过滤别名创建-最佳实践



我们计划使用这里提到的过滤别名- https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html

我们的输入数据将是一个流,流的每一行对应一个我们想要存储在ES中的对象。

每个对象都包含一个'id',用于路由和过滤。

——

问题如何以高性能的方式创建别名和索引数据?

—我们是否索引所有数据,跟踪所有唯一的"id",并在最后创建过滤别名?或者

——对于每个对象,检查是否存在对应的别名;如果它不创建一个?

我倾向于第一种方法。与第二种方法相比,它是可取的和高效的吗?

TIA。

根据我们上面的讨论,在浏览了您发表的博客文章之后,我非常肯定,在您的情况下,您根本不需要别名,路由密钥就足够了。再说一遍,仅仅因为你有一个指标,如果你有很多指标,这就不成立了!

您只需要指定索引文档时要使用的路由键。在ES 2.0之前,您可以将_routing字段用于此目的,尽管它在ES 1.5中已被弃用,但在您的情况下,它可以满足您的目的。

{
    "customer" : {
        "_routing" : {
            "required" : true,
            "path" : "customer_id"     <----- the field you use as the routing key
        },
        "properties": { ... }
    }
}

然后在搜索时,除了客户id过滤器外,您只需要在搜索URL中指定&routing=<customer_id>(因为给定的分片可以为不同的客户托管文档)。您的搜索将直接转到由给定路由键标识的分片,因此,只从指定的客户检索数据。

使用过滤别名不会带来任何东西,因为您在别名定义中包含的过滤器和路由键不会带来任何额外的东西,因为检索的文档已经被路由键"过滤"(某种程度上)了。这比尝试检测(在每个要索引的新文档上)别名是否存在并在不存在时创建别名要容易得多。

更新:

现在,如果你确实想创建过滤别名,更高效的方法是你提到的第一个:

  1. 首先索引您的每日数据
  2. 然后在size足够高的customer_id字段上运行terms聚合(即高于该字段的基数,在您的情况下为~100),以确保捕获所有唯一的客户id来创建您的别名
  3. 遍历所有桶以检索所有唯一的客户id
  4. 为每个customer_id创建一个action的所有别名
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" } }
            }
        },
        ...
    ]
}'

请注意,您不必担心别名是否已经存在,整个命令不会失败,并且会静默地忽略现有的别名。

当这个命令运行时,您将在您的唯一索引上拥有所有别名,并正确配置了过滤器和路由键。

最新更新