ElasticSearch Java API AggregationBuilder filter/global "name" 参数导致格式错误 JSON

ElasticSearch Java API AggregationBuilder filter/global "name" param causes malformed JSON

我试图使用 elasticsearch java API(版本 5.5.0)构建一个简单的聚合查询,但是 "name" 参数被AggregationBuilder 导致格式错误 JSON.

比如我试了第一个例子here... 这是相关的代码部分:

AggregationBuilder builder = 
  AggregationBuilders
  .global("agg")
  .subAggregation(AggregationBuilders.terms("genders").field("gender"));

Search search = new Search.Builder(builder.toString())
            .addIndex(INDEX_NAME)
            .addType(TYPE_NAME)
            .setParameter(Parameters.SIZE,0).build();

    JestClient jestClient = getJestClient();

    try {
        SearchResult result = jestClient.execute(search);
        System.out.println(result.getJsonString());
    } catch (IOException e) {
        e.printStackTrace();
    }

这会产生以下错误消息:

{
"error": {
"root_cause": [
  {
    "type": "parse_exception",
    "reason": "Failed to derive xcontent"
  }
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
  {
    "shard": 0,
    "index": "index_name",
    "node": "UEjNVXkIQRSBCOpyqcq2dw",
    "reason": {
      "type": "parse_exception",
      "reason": "Failed to derive xcontent"
    }
  }
]
},
"status": 400
}

在调试和观察构建器的值时,我看到它构建了以下格式错误的 JSON(请注意来自 "name" 参数的第一个元素("agg") "global" 方法):

"agg"{
  "global" : { },
  "aggregations" : {
    "genders" : {
      "terms" : {
        "field" : "gender",
        "size" : 10,
        "min_doc_count" : 1,
        "shard_min_doc_count" : 0,
        "show_term_doc_count_error" : false,
        "order" : [
          {
            "_count" : "desc"
          },
          {
            "_term" : "asc"
          }
        ]
      }
    }
  }
}

有什么想法吗?

使用最简单的示例,根据文档 (here and here),稍微修改您的代码,如下所示:

AggregationBuilder builder = AggregationBuilders.global("agg").subAggregation(AggregationBuilders.terms("genders").field("gender"));
SearchResponse response = client.prepareSearch(INDEX_NAME).setTypes(TYPE_NAME).setSize(0).addAggregation(builder).get();
//Global aggResult = response.getAggregations().get("agg"); //Global result can be used to retrieve values from the aggregation directly
System.out.println(response);

上面的代码(客户端初始化后)工作正常,因此 java API.

中的 AggregationBuilder 绝对没有问题

实际上我不明白您为什么不使用 SearchResponse class,因为它在文档中的所有示例中无所不在。

编辑:鉴于 link,我相信您的问题出在您创建搜索查询的方式上,因为您只使用聚合,给出您在 post 中显示的输出,而完整查询(Jest 客户端似乎需要)应该是这样的:

{
  "size" : 0,
  "aggregations" : {
    "agg" : {
      "global" : { },
      "aggregations" : {
        "genders" : {
          "terms" : {
            "field" : "gender",
            "size" : 10,
            "min_doc_count" : 1,
            "shard_min_doc_count" : 0,
            "show_term_doc_count_error" : false,
            "order" : [
              {
                "_count" : "desc"
              },
              {
                "_term" : "asc"
              }
            ]
          }
        }
      }
    }
  }
}

另一个编辑:实际上,一种解决方法是使用传输客户端构建查询,然后通过 JEST API 将其注入到搜索中,如下所示:

AggregationBuilder builder = AggregationBuilders.global("agg")
                .subAggregation(AggregationBuilders.terms("genders")
                        .field("gender"));
SearchRequestBuilder queryBuilder= client2.prepareSearch(INDEX_NAME)
        .setTypes(TYPE_NAME).setSize(0).addAggregation(builder); //client2 is a client initialized with the transport client
Search search = new Search.Builder(queryBuilder.toString()).addIndex("_all").addType("*").build();
SearchResult res = client.execute(search);
//          System.out.println(res.toString());
System.out.println(res.getJsonString());

P.S: 我用的也是5.5.0版本的Elasticsearch客户端API.