Following is the code screen shot
values of variables are
From debugging values are
Constants.NESTED_CATEGORY_ITEMIDS is
{ $arrayElemAt: [{ $arrayElemAt: [{ $arrayElemAt: ['$categories.subCategories.subCategories.itemIds',2]},2]},0]}
Constants.NESTED_CATEGORY_LEVEL is
categories.2.subCategories.2.subCategories.0.itemIds
Constants.NESTED_CATEGORY_VALUE is
categories.subCategories.subCategories.subCategoryName
menuId is 5e597a2be08a070bab329ef3
categoryName is Fish Taco
From debugging aggregation value is
{ "aggregate" : "__collection__", "pipeline" : [{ "$match" : { "_id" : { "$oid" : "5e597a2be08a070bab329ef3" }, "categories.subCategories.subCategories.subCategoryName" : "Fish Taco" } }, { "$project" : { "subCategories.subCategories.itemIds',2]},2]},0]}}]}" : "$categories.subCategories.subCategories.itemIds',2]},2]},0]}}]}" } }] }
after running mongotemplate aggregate with following payload
I am getting following error
Please help me in writing projections to get the Constants.NESTED_CATEGORY_ITEMIDS
wan
(Wan Bachtiar)
March 23, 2020, 1:14am
2
Hi @SatishReddy , welcome!
Assuming that you have the following document structure:
{
"menuId": "5e597a2be08a070bab329ef3",
"categories": [
{
"categoryName": "Dinner",
"level": 2,
"subCategories": [
{
"level": 0,
"subCategoryName": "Fish Taco",
"items": [ { "itemId": "bar" }, { "itemId": "foo" } ]
}
]
}
]
}
Using your example $arrayElemAt , here’s how you can use com.mongodb.client.model.Projections.computed() :
AggregateIterable<Document> iterable = collection.aggregate(Arrays.asList(
Aggregates.match(Filters.eq("menuId", "5e597a2be08a070bab329ef3")),
Aggregates.project(
Projections.fields(
Projections.computed(
"itemIds",
new Document("$arrayElemAt",
Arrays.asList(new Document("$arrayElemAt",
Arrays.asList(new Document("$arrayElemAt",
Arrays.asList("$categories.subCategories.items.itemId", 0)), 0)), 1))
)
)
)
));
Please see also MongoDB Java driver: Use Aggregation Expressions .
If you’re using spring-data MongoTemplate , make sure that the version supports the driver’s Projections.computed()
. The error that you posted looks like related to spring-data Mapping and MappingMongoConverter
, make sure that it supports Projections.computed()
as well.
Regards,
Wan.
1 Like
Thanks @wan . Using Projections.computed() returns Bson. Can you please let me know how to convert Bson to ProjectOperation or how to do using ProjectionOperation.
wan
(Wan Bachtiar)
April 1, 2020, 4:22am
4
Hi @SatishReddy ,
Perhaps you are trying to mix Aggregation between MongoDB Java driver and spring-data-mongodb Projection Operation . The above example is for MongoDB Java driver, if you’re using spring-data-mongodb you could try to use ArrayOperators.ArrayElemAt aggregation operator instead.
If you have further questions about the use of spring-data-mongodb, I’d suggest posting a question on StackOverflow: spring-data-mongodb to reach wider audience with the expertise.
Regards,
Wan
1 Like
What does the output (the result document fields and values) from the projection look like?
@Prasad_Saya
Using following document
{
"menuId": "5e597a2be08a070bab329ef3",
"categories": [
{
"categoryName": "Dinner",
"level": 2,
"subCategories": [
{
"level": 0,
"subCategoryName": "Fish Taco",
"items": [ { "itemId": "bar" }, { "itemId": "foo" } ]
}
]
}
]
}
how to get following result using ProjectionOperation
{"items": [ { "itemId": "bar" }, { "itemId": "foo" } ]}
SatishReddy:
how to get following result using ProjectionOperation
{“items”: [ { “itemId”: “bar” }, { “itemId”: “foo” } ]}
This is the MongoDB Spring Data (v2.2.6) code using MongoTemplate
, and returns the expected output document:
MongoOperations mongoOps = new MongoTemplate(MongoClients.create(), "test");
Aggregation agg = newAggregation(
project()
.and(arrayOf("categories.subCategories.items").elementAt(0))
.as("items")
.andExclude("_id")
);
AggregationResults<Document> results = mongoOps.aggregate(agg, "collection", Document.class);
results.forEach(doc -> System.out.println(doc.toJson()));
1 Like