Hi Team,
I have below query with me for which I am trying to build dynamically using Java API client.
{
"aggs": {
"country_aggr": {
"terms": {
"field": "country",
"size": 1000
},
"aggs": {
"state_aggr": {
"terms": {
"field": "state",
"size": 1000
},
"aggs": {
"city_aggr": {
"terms": {
"field": "city",
"size": 1000
}
}
}
}
}
}
}
}
Any help would be appreciated.
Thanks,
Ram Prasad
dadoonet
(David Pilato)
April 22, 2024, 2:48pm
2
Have a look at Switching from the Java High Level Rest Client to the new Java API Client | Elastic Blog
This might help you to find how to build your code.
An example of on agg in Java is also available at:
void termsAgg() throws IOException {
client.index(ir -> ir.index(indexName).id("1").withJson(new StringReader("{\"foo\":\"bar\"}")));
client.index(ir -> ir.index(indexName).id("2").withJson(new StringReader("{\"foo\":\"bar\"}")));
client.indices().refresh(rr -> rr.index(indexName));
SearchResponse<Void> response = client.search(sr -> sr
.index(indexName)
.aggregations("top10foo", a -> a.terms(ta -> ta.field("foo.keyword").size(10)))
, Void.class);
assertNotNull(response.aggregations().get("top10foo"));
assertNotNull(response.aggregations().get("top10foo").sterms());
assertNotNull(response.aggregations().get("top10foo").sterms().buckets());
assertEquals(1, response.aggregations().get("top10foo").sterms().buckets().array().size());
StringTermsBucket top10foo = response.aggregations().get("top10foo").sterms().buckets().array().get(0);
assertEquals("bar", top10foo.key().stringValue());
assertEquals(2, top10foo.docCount());
}
If you don't succeed, let us know and share what you did so far so we can iterate from that.
Hi dadoonet,
We are using Java API client. Currently we are preparing parent-child hierarchy based aggregation upfront using String (its not a recommended way) for different levels.
We tried to build this hierarchy dynamically based on the total number of fields, like below.
Aggregation aggr = Aggregation.of(t0 -> t0.terms(f0 -> f0.field(fields[0]).size(fieldSize[0])).aggregations(fields[1],
t1 -> t1.terms(f1 -> f1.field(fields[1]).size(fieldSize[1])).aggregations(fields[2],
t2 -> t2.terms(f2 -> f2.field(fields[2]).size(fieldSize[2])))));
But our requirement is, sub-aggregation should be appended to main aggregation within the iteration of fields.
Kindly let me know if my requirement is not clear.
Thanks,
Ram Prasad G
dadoonet
(David Pilato)
April 23, 2024, 11:32am
4
How should this look like using the QueryDSL?
It should look something like this,
Aggregation cityAggr = new Aggregation.Builder()
.terms(new TermsAggregation.Builder().field(CITY).build())
.build();
Map<String, Aggregation> cityAggrMap = new HashMap<>();
cityAggrMap.put(CITY_AGGR, cityAggr);
Aggregation stateAggr = new Aggregation.Builder()
.terms(new TermsAggregation.Builder().field(STATE).build()).aggregations(cityAggrMap)
.build();
Map<String, Aggregation> stateAggrMap = new HashMap<>();
stateAggrMap.put(STATE_AGGR, stateAggr);
Aggregation countryAggr = new Aggregation.Builder()
.terms(new TermsAggregation.Builder().field(COUNTRY).build()).aggregations(stateAggrMap)
.build();
Map<String, Aggregation> countryAggrMap = new HashMap<>();
countryAggrMap.put(COUNTRY_AGGR, countryAggr);
SearchRequest searchReq = SearchRequest.Builder().index(collection_name).size(0)
.aggregations(countryAggrMap)
.build();
In the above code, I am framing manually for 3 level of nested aggregation. This I need to frame dynamically.
Thanks,
Ram Prasad G
dadoonet
(David Pilato)
April 26, 2024, 9:47am
6
So you want something like this:
SearchResponse<Void> response = client.search(sr -> sr
.index(indexName)
.aggregations("country", a -> a.terms(ta -> ta.field("country"))
.aggregations("state", sa -> sa.terms(ta -> ta.field("state"))
.aggregations("city", ca -> ca.terms(ta -> ta.field("city")))
)
)
, Void.class);
But built depending on some conditions?