Elastic Java 客户端 returns 来自 HTTP API 的不同结果

Elastic Java client returns different result from HTTP API

我有一个应用程序正在使用 Elasticsearch Java API (5.6.7) 来执行聚合查询(术语)。我使用 curl 和 HTTP API 创建了以下搜索文档(显示相关信息):

{
  "from" : 0,
  "size" : 0,
  "sort" : [
    {
      "@timestamp" : {
        "order" : "desc"
      }
    }
  ],
  "aggregations" : {
    "level" : {
      "terms" : {
        "field" : "level.keyword",
        "size" : 10,
        "min_doc_count" : 1,
        "shard_min_doc_count" : 0,
        "show_term_doc_count_error" : false,
        "order" : [
          {
            "_count" : "desc"
          },
          {
            "_term" : "asc"
          }
        ]
      }
    }
  }
}

既然查询已在我的 Java 程序中实现,我注意到 结果与 HTTP API 结果不同

两者 return 完全 关于碎片、命中数等的相同元信息:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 3659,
    "max_score": 0.0,
    "hits": [

    ]
  }

然而,来自 Java API 的 returned 聚合不包含 任何桶:

  "aggregations": {
    "level": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [

      ]
    }

而来自 HTTP API 的相同聚合 包含桶:

  "aggregations": {
    "level": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "INFO",
          "doc_count": 2691
        },
        {
          "key": "WARN",
          "doc_count": 776
        },
        {
          "key": "ERROR",
          "doc_count": 192
        }
      ]
    }

我 100% 确定搜索文档是相同的(从 Java 应用日志中复制)。

问:造成这种差异的原因是什么?

编辑 我的 java 构建查询的代码是(包含很多对其他 类 的引用):

    // Start building the search itself
    SearchRequestBuilder srch = client.prepareSearch(indices.toArray(new String[indices.size()]))
            .setTypes(types.toArray(new String[types.size()])).setFrom(0).setSize(0);
    // Conditional sort order
    if (t.getOrder() != null)
        srch.addSort(t.getOrder().getBuilder());
    // Add aggregationbuilders to this search
    for (NivoStatistic stat : t.getStatistics())
    {
        logger.log(Level.FINER, "Adding statistic {0}", stat.getName());
        srch.addAggregation(stat.getContent());
    }
    // Use a search template    
    NivoQuery qry = t.getQuery();
    SearchTemplateRequestBuilder srchTemplate = new SearchTemplateRequestBuilder(client)
            .setRequest(srch.request())
            .setScript(qry.getTemplateString())
            .setScriptType(ScriptType.INLINE)
            .setScriptParams(qry.getParameterValues())
            ;
    logger.log(Level.FINER, "Prepared search: {0}", srchTemplate.request().getRequest().toString());

最后一个日志语句的输出是我通过 curl -XPOST http://localhost:9200/...

用于 POST 的

然后通过

执行
    // Execute the search
    try
    {
        SearchResponse resp = srchTemplate.get().getResponse();
        logger.log(Level.FINER, "Search returned: {0}", resp.toString());
        if (resp.status() == RestStatus.OK && resp.getAggregations() != null)
        {
            for (Aggregation agg : resp.getAggregations().asList())
            {
                // Update response
                t.getResponse().addStat(new NivoStatsHit(agg));
            }
        }
    }
    catch (ElasticsearchException e)
    {
        throw new ApiException(ApiExceptionCode.SEARCH_10061, "Database error: " + e.getDetailedMessage());
    }

我开始使用 Elasticserach 5.6.3 测试您的代码,虽然起初看起来可行,但后来我意识到并不那么容易。一切似乎都归结为搜索模板的使用。

您的代码的主要内容是您使用的是结合聚合的搜索模板。在我的测试中,甚至 sizefrom 也没有工作 ;-)。虽然不确定它对你有用。或者您可能还没有意识到结果还让您取回文档本身,因为它与您的 post 无关。您正在记录的查询看起来确实正确,但结果显示聚合 sizefrom 被忽略。

所以,此时我开始研究为什么搜索模板和聚合似乎不起作用(仅供参考,resp.getAggregations() returns null)。我发现了这个 - https://github.com/elastic/elasticsearch/issues/22766.

我尝试将搜索模板构建器与普通搜索请求相结合,但我失败了。