I have the following aggregation which Im not able to figure out how to represent in Java/Springboot mongodb driver.
db.metric.aggregate([
{ $match: { "key.runid":1} },
{ "$project": {
"data": {
"$filter": {
"input": { "$objectToArray": "$$ROOT.metricData" },
"cond": { "$ne": [ "$$this.k", "_id" ] }
}
}
}},
{ "$unwind": "$data" },
{ "$group": {
"_id": "$data.k",
"v": { "$avg": "$data.v" }
}},
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": null,
"data": { "$push": { "k": "$_id", "v": "$v" } }
}},
{ "$replaceRoot": {
"newRoot": { "$arrayToObject": "$data" }
}}
])
I have attempted the following but being new to this Im not able to figure out how to write the filter for the data field :
Aggregation aggregation = newAggregation(
match(getCriteriaForMetricKey(keys)),
project("data", ""));
Can someone help me out.
Related
we are migrating to elastic search 8 and when we are trying to fetch the data of parent document inner hits using has parent query .elastic search returning exception when runnning innerhits for has parent query.
https://discuss.elastic.co/t/inner-hits-in-has-parent-giving-error-couldnt-find-nested-source-for-path-currentcompany/318232
I had the same problem
bellow query giving me same error:, I had to pick parent document by using a field instead of _id
GET /user_data_factory/_search?from=0&size=20
{
"query": {
"bool": {
"must": [
{
"match": {
"relation_type": "uinsp"
}
},
{
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must": [
{
"match": {
"userInspirer": "63bef9f9a8c98000126589eb"
}
},
{
"bool": {
"minimum_should_match": 1,
"should": [
{
"has_parent": {
"parent_type": "user",
"query": {
"match": {
"_id": "63bd1ff29510390012760322"
}
},
"inner_hits": {
"_source": ["id"]
}
}
}]
}
}
]
}
}]
}
}
]
}
}
}
using field instead of _id
GET /user_data_factory/_search?from=0&size=20
{
"query": {
"bool": {
"must": [
{
"match": {
"relation_type": "uinsp"
}
},
{
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must": [
{
"match": {
"userInspirer": "63bef9f9a8c98000126589eb"
}
},
{
"bool": {
"minimum_should_match": 1,
"should": [
{
"has_parent": {
"parent_type": "user",
"query": {
"match": {
"id": "63bd1ff29510390012760322"
}
},
"inner_hits": {
"_source": ["id"]
}
}
}]
}
}
]
}
}]
}
}
]
}
}
}
So,suppose I have a document like :
{
"country": "USA",
"capital": "Washington DC",
"language": "English",
"other": {
"China": {
"capital": "Shanghai",
"language": "Chinese"
},
"Spain": {
"capital": "Madrid",
"language": "Spanish"
}
}
}
Now I want to return my document as:
{
"country": "USA",
"capital": "Washington DC",
"language": "English",
}
when I choose the country as "USA" but when I have the country set as "Spain", then I want my mongodb query to return the document as:
{
"country": "Spain",
"capital": "Madrid",
"language": "Spanish",
}
The fields should merge in accordance with the country specified in the "other" field.
How can I achieve this?
Try this one:
country = "Spain"
db.collection.aggregate([
// Make a uniform structure (why do you have 'USA' and 'other'?)
{ $replaceRoot: { newRoot: { $mergeObjects: ["$other", { USA: { capital: "$capital", language: "$language" } }] } } },
{ $project: { countries: { $objectToArray: "$$ROOT" } } },
{
$set: {
countries: {
$filter: {
input: "$countries",
cond: { $eq: ["$$this.k", country] }
}
}
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
{ country: { $first: "$countries.k" } },
{ $first: "$countries.v" }]
}
}
}
])
i have query
db.getCollection('collectionName').aggregate([
{
$project: {
'_id':1,
'arrayField': {
$filter: {
input: '$arrayField',
as: 'arrayField',
cond: { $or: [
{$eq: [ [LUUID("********-****-****-****-************")],['$$arrayField._id'] ] },
{$eq: [ [LUUID("********-****-****-****-************")],['$$arrayField._id'] ] }
] }
}
}
}
}])
How will it look in MongoTemplate? And it is possible to rewrite the cond?
cond rewritten as:
db.getCollection('collectionName').aggregate([
{
$project: {
'_id':1,
'arrayField': {
$filter: {
input: '$arrayField',
as: 'arrayField',
cond:
{ "$setIsSubset": [
{ "$map": {
"input": ["$$arrayField._id"],
"as": "el",
"in": "$$el"
}},
[ LUUID("********-****-****-****-************") ,LUUID("********-****-****-****-************")],
]}
}
}
}
}])
I get zero result when combining range filter and missing filter together in a query. Query is given below. I get this issue only while combining missing and range individually both works good.
Any help is appreciated on correcting the query or the code. I am elastic search 1.7.3 version.
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"bool": {
"should": {
"missing": {
"field": "OrderData.XXXX.XXXXQueue"
}
}
}
},
{
"range": {
"OrderData.XXXX.priority": {
"from": 1,
"to": 5,
"include_lower": true,
"include_upper": true
}
}
}
]
}
}
}
}
}
Does this Query get you the expected results?
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": {
"bool": {
"should": [{
"missing": {
"field": "OrderData.XXXX.XXXXQueue"
}
}, {
"range": {
"OrderData.XXXX.priority": {
"from": 1,
"to": 5,
"include_lower": true,
"include_upper": true
}
}
}]
}
}
}
}
}
}
}
I use
ElasticSearchTemplate().queryForPage(SearchQuery, CLASS)
How can I print the full json request?
I manage to print only filter by doing :
searchQuery.getFilter().toString()
But cant manage to do the same with:
searchQuery.getAggregations().toString();
I would like to print in console something like :
"aggs": {
"agg1": {
"terms": {
"field": "basket_id_1",
"size": 0
},
"aggs": {
"basket_id_2": {
"terms": {
"field": "basket_id_2",
"size": 0
},
"aggs": {
"basket_id_3": {
"terms": {
"field": "basket_id_3",
"size": 0
}
}
}
}
}
}
}
This is what I've started using to do the same thing.
{
"top_agg": {
"terms": {
"field": "id",
"size": 100
},
"aggregations": {
"parent": {
"nested": {
"path": "transactions"
},
"aggregations": {
"totals": {
"filter": {
"terms": {
"transactions.type": [
"ttype"
]
}
},
"total_events": {
"cardinality": {
"field": "parent.field"
}
}
}
}
}
}
}
}
NativeSearchQuery query = queryBuilder.build();
if (query.getQuery() != null) {
log.debug(query.getQuery().toString());
}
if (query.getAggregations() != null) {
try {
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
builder.startObject();
for (AbstractAggregationBuilder subAgg : query.getAggregations()) {
subAgg.toXContent(builder, ToXContent.EMPTY_PARAMS);
}
builder.endObject();
log.debug(builder.string());
} catch (IOException e) {
log.debug("Error parsing aggs");
}
}
Could you use the SearchResponse.getAggregations().asList() ?