我想使用Elasticsearch的聚合来进行OLAP数据分析。 我想要做的是将一个scriptedMetric聚合嵌套到一个术语聚合中,如下所示(它是正确的)
{
"from": 0,
"size": 0,
"query":{
"bool":{
"must":[
{
"match":{
"poi_id":1
}
}
]
}
},
"aggregations": {
"poi_id": {
"terms": {
"script": {
"inline": "doc['poi_id'].value + 1"
}
},
"aggregations": {
"price": {
"sum": {
"field": "price"
}
}
}
}
}
}
但我在Elasticsearch的java api中找不到如何做到这一点。
我已经这样试过了:
SearchResponse response = client.prepareSearch("poi")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setFetchSource(new String[]{"poi_id","poi_name"}, null)
.setQuery(QueryBuilders.termQuery("poi_id", 1))
.addAggregation(AggregationBuilders.terms("poi_id").subAggregation((AggregationBuilders.scriptedMetric("poi_id").mapScript(new Script("doc['poi_id'].value + 1")))))
.execute()
.actionGet();
但是出错了
Caused by: NotSerializableExceptionWrapper[: value source config is invalid; must have either a field context or a script or marked as unwrapped]; nested: IllegalStateException[value source config is invalid; must have either a field context or a script or marked as unwrapped];
我经常搜索,但无法找到演示。
任何帮助都将不胜感激。
谢谢!
答案 0 :(得分:0)
@Override
public Map<String, Object> sumPriceAggregation(String field, int page, int size) {
if (StringUtils.isEmpty(field)) {
field = "brandName";
}
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
PageRequest pageRequest = PageRequest.of(page, size);
queryBuilder.withPageable(pageRequest);
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[] {""}, null));
String termStr = field.toUpperCase();
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms(termStr)
.field(field)
.subAggregation(AggregationBuilders.sum("totalPrice").field("price")); //be aware this is subAggregation
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.addAggregation(termsAggregationBuilder);
AggregatedPage<GamingLaptop> aggregatedPage = elasticsearchRestTemplate.queryForPage(
nativeSearchQueryBuilder.build(), GamingLaptop.class);
Aggregations aggregations = aggregatedPage.getAggregations();
ParsedStringTerms stringTerms = aggregations.get(termStr);
List<? extends Terms.Bucket> buckets = stringTerms.getBuckets();
HashMap<String, Object> map = new HashMap<>();
buckets.parallelStream().forEach(bucket -> {
String key = bucket.getKeyAsString();
long docCount = bucket.getDocCount();
map.put(key, docCount);
ParsedSum sum = (ParsedSum) bucket.getAggregations().asMap().get("totalPrice"); //make sure you get the aggregation here
map.putIfAbsent("sum", sum.getValue());
});
return map;
}
'值源配置无效;必须具有字段上下文或脚本或标记为“未包装”。我也遇到此错误,请阅读代码中的注释,这是我的解决方案。需要检索 ParsedStringTerms 或 TermsAggregationBuilder 。