【问题标题】:Resulting all the indices while trying to get only those indices which are associated with specific alias在尝试仅获取与特定别名相关联的那些索引时生成所有索引
【发布时间】:2017-12-11 07:47:44
【问题描述】:

我最近将应用程序从 Elastic search 5.3.1 升级到了 6.0。

我的要求是获取与特定别名关联的所有索引。

我使用下面提到的 sn-p 来获取与特定别名关联的所有索引。这个 sn-p 在 5.3.1 中运行良好,并且只给出与该特定别名相关联的那些索引。

GetAliasesResponse r = client.admin().indices().getAliases(new 
GetAliasesRequest("givenalias")).actionGet();

但是在 ES 6.0 之后,相同的 sn-p 给出了在 system 中创建的所有索引。

理想情况下,它应该只返回那些与给定别名关联的索引。而不是其他索引。这在 Elastic search 5.3.1 中有效。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    TL;DR:它是 Elasticsearch 的 Java API 中的 intended breaking change(尽管在 "Breaking changes in 6.0 » Java API changes" 页面中没有明确提及)。

    以下是发现这一事实的故事。 (注意:原始答案经过大量编辑,因此 cmets 可能已过时。)

    6.0 中 REST API 的重大更改

    首先我注意到 REST API 的这一部分在 Elasticsearch 6.0 中发生了变化。有两个关于别名的重大变化报告:

    虽然没有提到任何关于 OP 的案例。

    从我看到的查询来看,这个查询在 Elasticsearch 5 中有效:

    GET /alias1/_aliases
    

    并且在 Elasticsearch 6 中不起作用,出现以下错误:

    {
      "error": "Incorrect HTTP method for uri [/alias1/_aliases] and method [GET], allowed: [PUT]",
      "status": 405
    }
    

    有趣的是,GET /alias1/_alias 在两个版本中都有效并且返回相同的结果。

    此外,我在 5.66.0 的文档中都没有找到 GET /alias1/_aliases 的示例。

    重现错误

    在意识到 OP 实际上是在使用 Java API 之后,我设法重现了完全相同的行为。

    以下代码:

    GetAliasesResponse alias1 = client.admin().indices()
        .getAliases(new GetAliasesRequest("alias1")).actionGet();
    

    在 ES 5 中,在 IntelliJ 调试器中生成:

    对于 ES 6,我有以下内容:

    如您所见,第二个输出中有额外的键,它们的值为空。

    深入研究源代码

    对 elasticsearch 代码库的快速搜索给了我最终的解释。在 ES 5 中有一个测试 testIndicesGetAliases 正在检查为测试别名返回的索引列表是否只有一个元素 (IndexAliasesIT.java#L554):

        logger.info("--> getting alias1");
        GetAliasesResponse getResponse = admin().indices().prepareGetAliases("alias1").get();
        assertThat(getResponse, notNullValue());
        assertThat(getResponse.getAliases().size(), equalTo(1));
    

    在 6.0 中,它会检查大小是否为 5! (IndexAliasesIT.java#L573)

        logger.info("--> getting alias1");
        GetAliasesResponse getResponse = admin().indices().prepareGetAliases("alias1").get();
        assertThat(getResponse, notNullValue());
        assertThat(getResponse.getAliases().size(), equalTo(5));
    

    这个变化是在this commit中引入的,与这些问题有关:

    这实际上很有趣,因为我们在上面看到的报告的 REST API 重大更改之一也破坏了某些 Java API 调用的兼容性。

    你能做什么

    短期内,您只需要过滤掉那些具有空值的键。

    从长远来看,我认为迁移到 Java High Level REST Client 是有意义的,因为 Elastic 计划在 7.0 版中使用 TransportClient deprecate

    我们计划在 Elasticsearch 7.0 中弃用 TransportClient 和 在 8.0 中完全删除它。相反,您应该使用 Java 高级 REST 客户端,它执行 HTTP 请求而不是 序列化的 Java 请求。

    一般来说,Elasticsearch 经常破坏兼容性,所以最好远离它的阴暗角落,比如 Java API。

    感谢阅读。

    希望有帮助!

    【讨论】:

    • 我同意你提到的所有观点。查询也是正确的。但我面临这个api的问题。它返回一个映射,其中包含索引作为键和别名作为值。当我在 ES5.3.1 上时,它只返回键(索引)属于给定别名(“givenalias”)的映射,但在 6.0 之后,它返回键中的所有索引,但有趣的是值(AliasMetaData)只对那些可用实际关联的索引。其他键索引 null 或空数组。我只是想找出为什么这个 api 会给出所有索引。这是 api 的不正确行为。
    • 客户端库也同步更新。它看起来是客户端库中的一个错误。因为http查询返回的是预期的结果但和api不一样。
    • @antitech 哪个是客户端库?
    • 弹性搜索客户端 6.0.0
    • @antitech 好的,现在我明白了,我以为您正在使用某种围绕 REST 的包装客户端,但实际上您使用的是本机 Java 客户端 (this one)。没用过所以不认识。我用最近的发现更新了答案。
    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    相关资源
    最近更新 更多