I am totally new to the Spring Data ES world and trying to create a list of aggregations in that each element has a "term" and another "aggs" like below and then add the main aggregation to my query at the end.
Also, I could not find the proper way of creating the "order" on the web.
{
"aggs":{ //add this to query
"item_one":{
"terms":{
"field":"A",
"size":70
},
"aggs":{
"item_one_inner":{
"terms":{
"field":"B",
"size":1000000
}
}
}
},
"item_two":{
"terms":{
"order":{
"_count":"desc"
},
"field":"C",
"size":70
},
"aggs":{
"item_two_inner":{
"terms":{
"field":"D",
"size":1000000
}
}
}
}
}
}
I have the code for the individual "terms" and "aggs". The Order is an example that I found on the web;
AggregationBuilder itemOneInner = AggregationBuilders
.terms("item_one_inner").field("B").size(1000000);
TermsAggregationBuilder itemOne = AggregationBuilders
.terms("item_one").field("A").size(70).subAggregation(itemOneInner);
TermsAggregationBuilder itemTwo = AggregationBuilders
.terms("item_two").field("C").size(70).order(Terms.Order.count(false));
AggregationBuilder itemTwoInner = AggregationBuilders
.terms("item_two_inner").field("D").size(1000000);
itemTwo.subAggregation(itemTwoInner);
Finally, add the main Aggregation to my query;
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(finalQuery).addAggregation(mainAgg).build();
Any help would be appericated. Thanks
Related
I'm new in ElasticSearch world. I've been trying write simple request and I need to get aggs result in my script to make simple condition. Is it possible to do it in this way?
The condition below is only for example.
GET _search
{
"aggs" : {
"sum_field" : { "sum" : { "field" : "someField" } }
},
"script_fields": {
"script_name": {
"script": {
"lang": "painless",
"source": """
// get there aggs result (sum_field)
if(sum_field > 5){
return sum_field
}
"""
}
}
}
}
The requirement is to execute sum aggregation over multiple indexes having the same field name
Now with multiple indexes, you'll have to check if that particular field exists in that indexes or not AND if the field is of the same datatype.
Indexes
I've created three indexes, having a single field called num.
index_1
- num: long
index_2
- num: long
index_3
- num: text
: fielddata: true
Also notice how if the field is of type text, then I've set its property fielddata:true. But if you do not set it, then the below query would give you aggregation result as well as an error saying you cannot retrieve the value of type text as its an analyzed string and you can only use doc for fields which are non_analyzed.
Sample Query:
POST /_search
{
"size":0,
"query":{
"bool":{
"filter":[
{
"exists":{
"field":"num"
}
}
]
}
},
"aggs":{
"myaggs":{
"sum":{
"script":{
"source":"if(doc['num'].value instanceof long) return doc['num'].value;"
}
}
}
}
}
Query if you cannot set fielddata:true
In that case, you need to explicitly mention the indexes on which you'd want to aggregate.
POST /_search
{
"size":0,
"query":{
"bool":{
"filter":[
{
"exists":{
"field":"num"
}
},
{
"terms":{
"_index":[
"index_1",
"index_2"
]
}
}
]
}
},
"aggs":{
"myaggs":{
"sum":{
"script":{
"source":"if(doc['num'].value instanceof long) return doc['num'].value;"
}
}
}
}
}
Hope this helps!
I am using elasticsearch for creating some aggregation reports. Here is my aggregation query
{
"size":10,
"_source":["country_iso", "username"],
"aggs":{
"Granulated Reports":{
"date_histogram" :{
"field":"aggr_time",
"interval" : "month"
},
"aggs":{
"calls":{
"sum":{"field":"bill_duration"}
}
}
}
}
}
I get a doc_count of 27000 but if I remove the aggregation calls and make it
{
"size":10,
"_source":["country_iso", "username"],
"aggs":{
"Granulated Reports":{
"date_histogram" :{
"field":"aggr_time",
"interval" : "month"
},
"aggs":{
}
}
}
}
I am getting a doc_count of 44000. My understanding is that the doc_count should differ only if i change a query or a filter. Adding or deleting aggregations should not have any effect on the number of documents it is scanning. The Doc_count goes down if I add another aggregation. I am not able to understand this behavior as this is giving different answers based on the number of aggregations.
I are working on Elastic Search and trying to fetch data by using aggregation queries from angularjs UI pages, we are using Elasticseach.js, Elastic.js etc plugins for
posting the request and getting the response, everything is working here for me except Date Range filters means Range filters is not working.
Below is my query which i am using for posting a request:-
var filters = [ejs.RangeFilter('purchaseDate').gte(this.startDate).lte(this.endDate)];
var composedFilter = ejs.AndFilter(filters);
var myQuery = ejs.TermsAggregation('parentsku')
.field(skufield.value)
.order("_term", "asc")
.size(0)
.agg(ejs.StatsAggregation('cost').field('directCost'))
.agg(ejs.StatsAggregation('sales').field('revenu'))
.agg(ejs.StatsAggregation('salesQuantity').field('salesQuantity'))
.agg(ejs.StatsAggregation('quantity').field('quantity'))
.agg(ejs.FilterAggregation('filtered').filter(composedFilter));
Here "purchaseDate" is the field in Elastic search Index on which i am trying to apply range filter.
Its json form of this is:-
{
"aggs":{
"parentsku":{
"terms":{
"field":"parentSku",
"order":{
"_term":"asc"
},
"size":0
},
"aggs":{
"cost":{
"stats":{
"field":"directCost"
}
},
"sales":{
"stats":{
"field":"revenu"
}
},
"salesQuantity":{
"stats":{
"field":"salesQuantity"
}
},
"quantity":{
"stats":{
"field":"quantity"
}
},
"filtered":{
"filter":{
"and":{
"filters":[
{
"range":{
"purchaseDate":{
"gte":"2016-03-01",
"lte":"2016-04-10"
}
}
}
]
}
}
}
}
}
}
}
I need help if anyone can that would be appreciated.
I am trying to get extra field with aggregation. Below is the query
GET /iacmpi/_search?_source=false
{
"query": {
"match": {
"Document_Type": "INVOICEDoc"
}
},
"aggs": {
"GroupByCDMInvoiceID": {
"terms":{ "field" : "INVOICE_ID" },
"aggs":{
"LatestVersion":{
"max":{
"field":"DocVersion"
}
}
}
}
}
}
So at the level of INVOICE_ID field aggregation, i need to fetch one more field 'NAME'. I dont want that in query part as it will show me all hits and i have to traverse the hits and get a match.
Is it possible?
Thanks,
Sameer
I think top hits is what you're looking for.
When I execute the query below, how to paging the aggs results?
And is there a method to put the aggs results to hits part in json result?
POST http://myElastic.com/test/e1,e2,e3/_search
{
"aggs":{
"dedup" : {
"terms":{
"field": "id"
},
"aggs":{
"dedup_docs":{
"top_hits":{
"size":1
}
}
}
}
}
}
I searched a moment before found and I came across several positions during my research, so I post a new answer for people who will make the same journey as me.
We can partition the results as below:
{
"aggs":{
"group" : {
"terms":{
"field": "id",
"size":5000,
"include": {
"partition": 1,
"num_partitions": 1000
}
},
"aggs":{
"dedup_docs":{
"top_hits":{
"size":1
}
}
}
}
}
}
// size:5000 : return 5.000 results per page
// num_partitions:1000 : return 1.000 pages of results
// partition:1 : return page index 1 (start at 0)
// size:5000,num_partitions:1000,partition:1 : returns results from 5.000 to 9.999
// size:5000,num_partitions:1000,partition:2 : returns results from 10.000 to 14.999
// size:5000,num_partitions:1000,partition:3 : returns results from 15.000 to 19.999
Based on the below issue on the Elasticsearch github site I don't think what you are asking for is possible:
https://github.com/elastic/elasticsearch/issues/4915
Seems like a common request however. Add your own feedback and they may get around to adding it.