I am new to programming and I want to get the sum of power used in a month from a data stored in elasticsearch, I've used sense and got the value but still finding it hard using Java API in scala. This is what I did
POST /myIndext/myType/_search?search_type=dfs_query_then_fetch
{
"aggs": {
"duration": {
"date_histogram": {
"field": "Day",
"interval": "month",
"format": "yyyy-MM-dd"},
"aggs": {
"Power_total": {
"sum": {
"field": "myField"
}
}
}
}
}
}
RESULT WAS
( "aggregations": {
"duration": {
"buckets": [
{
"key_as_string": "2017-01-01",
"key": 1480550400000,
"doc_count": 619,
"myField": {
"value": 5218.066633789334
}
}
Then scala code is this
val matchquery = QueryBuilders.matchQuery("ID", configurate)
val queryK = QueryBuilders.matchQuery("ID", configurate)
val filterA = QueryBuilders.rangeQuery("Day").gte("2017-01-02T00:00:05.383+0100").lte("2017-01-13T00:00:05.383+0100")
val query = QueryBuilders.filteredQuery(queryK, filteAr)
val agg = AggregationBuilders.dateHistogram("duration")
.field("Day")
.interval(DateHistogramInterval.MONTH)
.minDocCount(0)
.extendedBounds(new DateTime("2017-01-01T00:00:05.383+0100"), new DateTime("2017-01-13T00:00:05.383+0100"))
.subAggregation(AggregationBuilders.sum("power_total").field("myField"))
val result: SearchResponse = client
.prepareSearch("myIndex")
.setTypes("myType")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(query)
.addAggregation(agg)
.addSort("Day", SortOrder.DESC)
.setSize(815)
.addField("myField")
.execute()
.actionGet()
val results = result.getHits.getHits
println("Current results: " + results.length)
for (hit <- results) {
println("------------------------------")
val response = hit.getSource
println(response)
}
client.close()
RESULT WAS
current result = 0
Please let me know why am not getting value for "myField" like I got using sense.
I have tried doing it severally and still get same errors, could it be that I don't parse the query response the right way?
Everything was correct the only pitfall was that I was querying a date time not stored stored in my database. so instead of "2017-01-01", I was inserting this "2017-01-02"
Related
I am trying to use the ElasticSearch Java APIs to do a query-string-query and then restrict the results by a date range based on a field in the result set. When I test it out using Kibana I get 77 hits but when I try to do the same thing using the Java APIs I get '0' hits.
Here is the query as written in Kibana:
GET /enyo_cad/_search
{
"from": 0, "size": 20,
"query": {
"query_string": {
"query": "smith",
"lenient": true
}
},
"post_filter": {
"range": {
"cadIncident.dateTimeReceived": {
"gte": "2014-01-01T00:00:00",
"lte": "2016-01-01T00:00:00"
}
}
},
"highlight": {
"fields": {
"*": {}
},
"require_field_match": false
},
"sort": [
{ "cadIncident.dateTimeReceived": { "order": "desc" }},
{ "_score": { "order": "desc" }}
]
}
And here is my Java code:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.queryStringQuery(searchString)
.lenient(Boolean.TRUE)
.analyzeWildcard(Boolean.TRUE)
);
searchSourceBuilder.from(fromHit);
searchSourceBuilder.size(pageSize);
if (startDate != null && endDate != null) {
String dtName = getDateTimeAttributeName(appList, radarManager);
searchSourceBuilder.postFilter(QueryBuilders.rangeQuery(dtName)
.gte(startDate)
.lte(endDate));
}
// This section will sort the results IF there is only 1 application module selected OTHERWISE default revelvance score based sorting will continue.
if (dateSort && appList.size() == 1) {
searchSourceBuilder.sort(getDateTimeAttributeName(appList, radarManager), SortOrder.DESC);
searchSourceBuilder.sort("_score", SortOrder.DESC);
}
HighlightBuilder highlightBuilder = new HighlightBuilder();
HighlightBuilder.Field highlightFields = new HighlightBuilder.Field("*");
highlightFields.highlighterType("unified"); //highlighter type unified is default https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html
highlightBuilder.field(highlightFields);
searchSourceBuilder.highlighter(highlightBuilder);
searchRequest.source(searchSourceBuilder);
searchRequest.indices(indexFilter);
searchResponse = restClient.search(searchRequest, requestOptions);
SearchHits hits = searchResponse.getHits();
Any help would be greatly appreciated..
Found the solution.. Sorry for the post when it was just a simple missing pair of parentheses .. should have been
if (dateSort && (appList.size() == 1)) {
I want to code elasticsearch aggregation in JAVA API to find field collapsing and result grouping.
The json aggregation code is shown below
I've got these code from elasticsearch docs
'dedup_by_score' aggregation has sub aggregation called 'top_hit' aggregation
and use this in terms aggregation for bucket ordering.
... some query
"aggs": {
"dedup_by_score": {
"terms": {
"field": "keyword",
"order": {
"top_hit": "desc"
},
"size": 10
},
"aggs": {
"top_hit": {
"max": {
"script": {
"source": "_score"
}
}
}
}
}
}
I want to convert this json query into JAVA
And this is what I've already tried in JAVA
AggregationBuilder aggregation = AggregationBuilders.terms("dedup_by_score")
.field("keyword")
.order(BucketOrder.aggregation("top_hit", false))
.size(10)
.subAggregation(
AggregationBuilders.topHits("top_hit")
.subAggregation(
AggregationBuilders.max("max").script(new Script("_score"))
)
);
But I got an error like below from Elasticsearch
{
"type":"aggregation_initialization_exception",
"reason":"Aggregator [top_hit] of type [top_hits] cannot accept sub-aggregations"
}
How can I fix this Java code? I'm using Elasticsearch 6.7.1 version now.
Thanks in advance
Top hit aggs can't have sub-aggs. Try this:
AggregationBuilder aggregation = AggregationBuilders.terms("dedup_by_score")
.field("keyword")
.order(BucketOrder.aggregation("top_hit", false))
.size(10)
.subAggregation(
AggregationBuilders.max("max").script(new Script("_score"))
.subAggregation(
AggregationBuilders.topHits("top_hit")
)
);
I have a json query version of adding sum of two fields in aggregations like this -
"aggs": {
"field1Sum": {
"sum": {
"field": "field1"
}
},
"field2Sum": {
"sum": {
"field": "field2"
}
}
}
I need to convert my data into this query using Java QueryBuilder for Elasticsearch
So far -
SumBuilder s1 = AggregationBuilders.sum(field2Sum).field(field2);
SumBuilder s2 = AggregationBuilders.sum(field1Sum).field(field1);
Any help?
SearchResponse sr = client.prepareSearch()
.setQuery(QueryBuilders.matchAllQuery())
.addAggregation(
AggregationBuilders.sum(field2Sum).field(field2)
)
.addAggregation(
AggregationBuilders.sum(field1Sum).field(field1)
)
.get();
Link
This is my code in Marvel Sense:
GET /sweet/cake/_search
{
"query": {
"bool": {
"must": [
{"term": {
"code":"18"
}}
]
}
},
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "id"
}
}
}
}
And I want to write it in Java but I dont't know how.
You can find some examples in the official documentation for the Java client.
But in your case, you need to create one bool/must query using the QueryBuilders and one terms aggregation using the AggregationBuilders. It goes like this:
// build the query
BoolQueryBuilder query = QueryBuilders.boolFilter()
.must(QueryBuilders.termFilter("code", "18"));
// build the terms sub-aggregation
TermsAggregation stateAgg = AggregationBuilders.terms("group_by_state")
.field("id");
SearchResponse resp = client.prepareSearch("sweet")
.setType("cake")
.setQuery(query)
.setSize(0)
.addAggregation(stateAgg)
.execute()
.actionGet();
I want to extract all these places mentioned in "location" field and does not want the other fields in the below json.but can't be able to extract since it is nested..Can anyone help me?
DBCursor cursorTotal = coll.find(obje);
while (cursorTotal.hasNext()) {
DBObject curNext = cursorTotal.next();
System.out.println("data::"+curNext.get("list.myList.location");
}
My "curNext" gives output as::
{
"_id": {
"$oid": "51ebe983e4b0d529b4df2a0e"
},
"date": {
"$date": "2013-07-21T13:31:11.000Z"
},
"lTitle": "Three held for running CISF job racket",
"list": {
"myList": [
{
"location": "Germany"
},
{
"location": "Geneva"
},
{
"location": "Paris"
}
]
},
"hash": -1535814113,
"category": "news"
}
I want my output as
Germany,Geneva,Paris
I have been in a long wait here for an answer and finally I got what I was searching for...Just noting my answer so someone else can benefit from it
DBCursor cursorTotal = coll.find(obje);
while (cursorTotal.hasNext()) {
DBObject curNext = cursorTotal.next();
String res=curNext.toString();
JsonElement jelement = new JsonParser().parse(res);
JsonObject jobject = jelement.getAsJsonObject();
jobject = jobject.getAsJsonObject("list");
JsonArray jarray = jobject.getAsJsonArray("myList");
jobject = jarray.get(0).getAsJsonObject();
String result = jobject.get("location").getAsString();
System.out.println("all places::"+result);
}
For finding only locations you should used mongo aggregation, below query will fetch all lcoations array
db.collectionName.aggregate({
"$unwind": "$ner.nerList"
},
{
"$group": {
"_id": "$_id",
"location": {
"$push": "$ner.nerList.location"
}
}
},
{
"$project": {
"location": "$location",
"_id": 0
}
})
Unfortunately I don't know how to convert this in Java but, I find below links which helpfull to you for converting above query in java format
Mongo Java aggregation driver