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 测试您的代码,虽然起初看起来可行,但后来我意识到并不那么容易。一切似乎都归结为搜索模板的使用。
您的代码的主要内容是您使用的是结合聚合的搜索模板。在我的测试中,甚至 size
和 from
也没有工作 ;-)。虽然不确定它对你有用。或者您可能还没有意识到结果还让您取回文档本身,因为它与您的 post 无关。您正在记录的查询看起来确实正确,但结果显示聚合 size
和 from
被忽略。
所以,此时我开始研究为什么搜索模板和聚合似乎不起作用(仅供参考,resp.getAggregations()
returns null
)。我发现了这个 - https://github.com/elastic/elasticsearch/issues/22766.
我尝试将搜索模板构建器与普通搜索请求相结合,但我失败了。
我有一个应用程序正在使用 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/...
然后通过
执行 // 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 测试您的代码,虽然起初看起来可行,但后来我意识到并不那么容易。一切似乎都归结为搜索模板的使用。
您的代码的主要内容是您使用的是结合聚合的搜索模板。在我的测试中,甚至 size
和 from
也没有工作 ;-)。虽然不确定它对你有用。或者您可能还没有意识到结果还让您取回文档本身,因为它与您的 post 无关。您正在记录的查询看起来确实正确,但结果显示聚合 size
和 from
被忽略。
所以,此时我开始研究为什么搜索模板和聚合似乎不起作用(仅供参考,resp.getAggregations()
returns null
)。我发现了这个 - https://github.com/elastic/elasticsearch/issues/22766.
我尝试将搜索模板构建器与普通搜索请求相结合,但我失败了。