我有一个使用 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结果不同!
两者都返回完全相同的关于分片,命中数等的元信息:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3659,
"max_score": 0.0,
"hits": [
]
}
但是,Java API 返回的聚合不包含任何存储桶:
"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());
}
答案 0 :(得分:3)
我开始使用Elasticserach 5.6.3测试你的代码,虽然起初它看起来很可行,但我意识到并不那么容易。所有这些似乎归结为搜索模板的使用。
您的代码的主要内容是您使用的搜索模板与聚合相结合。在我的测试中,即使size
和from
也没有工作;-)。不知道它对你有什么用。或许您还没有意识到结果也会让您自己回复文档,因为它与您的帖子无关。您正在记录的查询确实看起来正确,但结果显示聚合size
和from
会被忽略。
所以,在这一点上,我开始研究为什么搜索模板和聚合似乎不起作用(fyi,resp.getAggregations()
返回null
)。我发现了这个 - https://github.com/elastic/elasticsearch/issues/22766。
我尝试将搜索模板构建器与普通搜索请求相结合,但我失败了。