update or replace the mongoose nested array object - mongodb

I have a timesheet schema which results as below and I want to replace single data array object by a new set of values in mongoose. Either i want remove already existing object and push a new set of values or update the old object with new values.Please suggest me a proper way to achieve this. I am was struggled a lot to do this, because i am new to mongoose and mongodb. Thanks in advance
{
"_id": ObjectId("53f1fb3401ea96440d62646b"),
"user_id": "andrew",
"type": "Solutions",
"timesheets": [{
"weekStartDate": ISODate("2014-08-18T00:00:00Z"),
"weekEndDate": ISODate("2014-08-22T00:00:00Z"),
"_id": ObjectId("53f1fb3401ea96440d62646c"),
"data": [{
"date": ISODate("2014-08-18T00:00:00Z"),
"_id": ObjectId("53f1fb3401ea96440d62646d"),
"record": [{
"_id": ObjectId("53f1fb3401ea96440d626470"),
"desc": "",
"cellId": "0:0",
"custName": "Coach",
"custID": "2",
"timeSpend": "04:00",
"categoryName": "Billing",
"categoryID": "1"
}, {
"_id": ObjectId("53f1fb3401ea96440d62646f"),
"desc": "Description",
"cellId": "0:1",
"custName": "",
"custID": "",
"timeSpend": "05:00",
"categoryName": "Solution",
"categoryID": "4"
}, {
"_id": ObjectId("53f1fb3401ea96440d62646e"),
"desc": "Description",
"cellId": "0:2",
"custName": "",
"custID": "",
"timeSpend": "06:00",
"categoryName": "GTM",
"categoryID": "3"
}],
"savedFlag": false,
"submitFlag": false
}, {
"date": ISODate("2014-08-19T00:00:00Z"),
"_id": ObjectId("53f1fb4e01ea96440d626471"),
"record": [{
"_id": ObjectId("53f1fb4e01ea96440d626474"),
"desc": "",
"cellId": "1:0",
"custName": "Morgan",
"custID": "3",
"timeSpend": "04:00",
"categoryName": "RFP",
"categoryID": "2"
}, {
"_id": ObjectId("53f1fb4e01ea96440d626473"),
"desc": "",
"cellId": "1:1",
"custName": "Morgan",
"custID": "3",
"timeSpend": "05:00",
"categoryName": "RFP",
"categoryID": "2"
}, {
"_id": ObjectId("53f1fb4e01ea96440d626472"),
"desc": "",
"cellId": "1:2",
"custName": "Citi",
"custID": "1",
"timeSpend": "04:00",
"categoryName": "Sales",
"categoryID": "0"
}],
"savedFlag": false,
"submitFlag": false
}],
"savedFlag": true,
"submitFlag": false
}],
"__v": 0
} >

Related

Category hierarchy in mongodb

My document structure is as follows:
[
{
"_id": ObjectId("54d81827e4a4449d023b4e34"),
"name": "Refridgerator",
"parent": null,
"slug": "refridgerator"
},
{
"_id": ObjectId("54d818227e4a4449d023b4e34"),
"name": "Generator",
"parent": null,
"slug": "generator",
},
{
"_id": ObjectId("54dc38bcse4a4449d023b4e58"),
"name": "Bolt",
"slug": "bolt",
"parent": ObjectId("54d818227e4a4449d023b4e34")
},
{
"_id": ObjectId("54dc38bce4a4449d023b4e58"),
"name": "Ice Cream",
"slug": "ice-cream",
"parent": ObjectId("54d81827e4a4449d023b4e34")
},
{
"_id": ObjectId("54dc3705e4a4449d023b4e56"),
"name": "Chocolate",
"slug": "chocolate",
"parent": ObjectId("54d81827e4a4449d023b4e34")
},
{
"_id": ObjectId("54dc38bce4a4449d023b4e68"),
"name": "Mango Cream",
"slug": "mango-cream",
"parent": ObjectId("54dc38bce4a4449d023b4e58")
},
{
"_id": ObjectId("54dc38bc74a4449d023b4e68"),
"name": "Mango Cream Cream",
"slug": "mango-cream-cream",
"parent": ObjectId("54dc38bce4a4449d023b4e68")
},
]
I’m making a category hierarchy using mongodb and its like parent-child relationship. Category is of 4 level.
Now I wish to query for _id = ‘54d81827e4a4449d023b4e34’ and should get back all the child categories.
I’m unable to get the json structured with parent – child relations.
In previous asked question does not output the required result.
Expected Output:
[
{
"_id": ObjectId("54d81827e4a4449d023b4e34"),
"name": "Refridgerator",
"parent": null,
"slug": "refridgerator",
"subCategory": [
{
"_id": ObjectId("54dc3705e4a4449d023b4e56"),
"name": "Chocolate",
"parent": ObjectId("54d81827e4a4449d023b4e34"),
"slug": "chocolate"
},
{
"_id": ObjectId("54dc38bce4a4449d023b4e58"),
"name": "Ice Cream",
"parent": ObjectId("54d81827e4a4449d023b4e34"),
"slug": "ice-cream",
'subsubcategory':[
{
"_id": ObjectId("54dc38bce4a4449d023b4e68"),
"name": "Mango Cream",
"slug": "mango-cream",
"parent": ObjectId("54dc38bce4a4449d023b4e58"),
'subsubsubcategory':[
{
"_id": ObjectId("54dc38bc74a4449d023b4e68"),
"name": "Mango Cream Cream",
"slug": "mango-cream-cream",
"parent": ObjectId("54dc38bce4a4449d023b4e68")
},
]
}
]
}
]
},
{
"_id": ObjectId("54d818227e4a4449d023b4e34"),
"name": "Generator",
"parent": null,
"slug": "generator",
"subCategory": [
{
"_id": ObjectId("54dc38bcse4a4449d023b4e58"),
"name": "Bolt",
"slug": "bolt",
"parent": ObjectId("54d818227e4a4449d023b4e34")
},
]
}
]

getting last 3 lookup documents sorted by field on mongodb

I'm new to mongodb query programming. I just need to get the last 3 comments for posts ordered by datetime (desc). Here's my collections structure:
post = {
text : "string",
imgs: "array",
video: "string",
videoImage: "string",
datetime: "datetime",
user: "object",
tags: "array",
status: "string",
category:'string',
tags:'array'
}
post_comments = {
text : "string",
datetime: "string",
user: "object",
post: "array"
}
I wrote the aggregate parameters as follows
[
{"$match": {"status":"online"}},
{"$lookup": {"from":"users","localField":"user","foreignField":"_id","as":"user"}},
{"$lookup":{"from":"post_comments","localField":"_id","foreignField":"post","as":"comments"}},
{"$sort":{"datetime":-1}},
{"$project":{
"text":1,
"imgs":1,
"video":1,
"tags":1,
"videoImage":1,
"datetime":1,
"user": {
"_id":1,
"name":1,
"username":1,
"city":1,
"location":1,
"accountType":1,
"language":1,
},
"category":1,
"three_comments":{
{$reverseArray: '$comments'},
{$slice: ['$three_comments', 3]}
}
}}
]
But the result is not what expected. The tree_comments array is correctly ordered but it doesn't return 3 comments. it returns all comments.
[{
"_id": "5af94b4d71f33811513b4b79",
"category": "music",
"video": "",
"imgs": [],
"videoImage": false,
"text": "post",
"tags": [],
"datetime": 1526621841973,
"user": [{
"_id": "FuRRTBEYBmCSDPJkN",
"username": "user",
"language": "it",
}],
"three_comments": [
[{
"_id": "5afe669169130aeecc9c9ac8",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "33",
"datetime": 1526621841844
}, {
"_id": "5af94b96119abe115ad7aff6",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "22",
"timestamp": 1526287254793
}, {
"_id": "5af94b94119abe115ad7aff5",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "11",
"timestamp": 1526287252138
}, {
"_id": "5af94b76119abe115ad7aff4",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "00",
"timestamp": 1526287222566
}, {
"_id": "5af94b5271f33811513b4b7a",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": null,
"timestamp": 1526287186595
}], null
]
}, {
"_id": "5afd1cff2fc69da9adb3c973",
"category": "music",
"video": "https://www.youtube.com/embed/123",
"imgs": ["http://localhost:3002/uploads/images/post/42018/1526537471269.jpg", "http://localhost:3002/uploads/images/post/42018/1526537471403.jpg", "http://localhost:3002/uploads/images/post/42018/1526537471521.jpeg"],
"videoImage": "https://i.ytimg.com/vi/123/321.jpg",
"text": "second post",
"tags": [],
"datetime": 1526621816648,
"user": [{
"_id": "FuRRTBEYBmCSDPJkN",
"username": "user",
"language": "it",
}],
"three_comments": [
[{
"_id": "5afe667869130aeecc9c9ac7",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "5",
"datetime": 1526621816517
}, {
"_id": "5afd1dcd2fc69da9adb3c977",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "4",
"timestamp": 1526537677768
}, {
"_id": "5afd1dc72fc69da9adb3c976",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "3",
"timestamp": 1526537671316
}, {
"_id": "5afd1dc12fc69da9adb3c975",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "2",
"timestamp": 1526537665091
}, {
"_id": "5afd1da42fc69da9adb3c974",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "1",
"timestamp": 1526537636677
}], null
]
}]
I tried to (as suggested ) to slice the $comments array instead of $three_comments and the result is strange (see follows)
[{
"_id": "5afd1cff2fc69da9adb3c973",
"category": "music",
"video": "https://www.youtube.com/embed/123",
"imgs": ["http://localhost:3002/uploads/images/post/42018/1526537471269.jpg", "http://localhost:3002/uploads/images/post/42018/1526537471403.jpg", "http://localhost:3002/uploads/images/post/42018/1526537471521.jpeg"],
"videoImage": "https://i.ytimg.com/vi/321/123.jpg",
"text": "text",
"tags": [],
"datetime": 1526735767676,
"user": [{
"_id": "FuRRTBEYBmCSDPJkN",
"username": "user",
"language": "it",
}],
"marketplace": [],
"three_comments": [
[{
"_id": "5b00239771dd135081e1b3e1",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "3",
"datetime": 1526735767500
}, {
"_id": "5afe667869130aeecc9c9ac7",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "2",
"datetime": 1526621816517
}, {
"_id": "5afd1dcd2fc69da9adb3c977",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "1",
"timestamp": 1526537677768
}, {
"_id": "5afd1dc72fc69da9adb3c976",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "11",
"timestamp": 1526537671316
}, {
"_id": "5afd1dc12fc69da9adb3c975",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "111",
"timestamp": 1526537665091
}, {
"_id": "5afd1da42fc69da9adb3c974",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "111",
"timestamp": 1526537636677
}],
[{
"_id": "5afd1da42fc69da9adb3c974",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "3",
"timestamp": 1526537636677
}, {
"_id": "5afd1dc12fc69da9adb3c975",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "2",
"timestamp": 1526537665091
}, {
"_id": "5afd1dc72fc69da9adb3c976",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5afd1cff2fc69da9adb3c973",
"text": "1",
"timestamp": 1526537671316
}]
]
}, {
"_id": "5af94b4d71f33811513b4b79",
"category": "music",
"video": "",
"imgs": [],
"videoImage": false,
"text": "post",
"tags": [],
"datetime": 1526723943037,
"user": [{
"_id": "FuRRTBEYBmCSDPJkN",
"username": "user",
"language": "it",
}],
"three_comments": [
[{
"_id": "5afff566b52b3447548fa0d1",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "33",
"datetime": 1526723942934
}, {
"_id": "5afff527b52b3447548fa0d0",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "22",
"datetime": 1526723879879
}, {
"_id": "5afff4cedc81f44731af6da1",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "11",
"datetime": 1526723790513
}, {
"_id": "5afff4a26f0138470d7b48e8",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "111",
"datetime": 1526723746622
}, {
"_id": "5afff4886f0138470d7b48e7",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "1111",
"datetime": 1526723720873
}, {
"_id": "5afff43fd4ef4445101e8bfc",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "11111",
"datetime": 1526723647463
}, {
"_id": "5afe669169130aeecc9c9ac8",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "111111",
"datetime": 1526621841844
}, {
"_id": "5af94b96119abe115ad7aff6",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "1111111",
"timestamp": 1526287254793
}, {
"_id": "5af94b94119abe115ad7aff5",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "11111111",
"timestamp": 1526287252138
}, {
"_id": "5af94b76119abe115ad7aff4",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "111111111",
"timestamp": 1526287222566
}, {
"_id": "5af94b5271f33811513b4b7a",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": null,
"timestamp": 1526287186595
}],
[{
"_id": "5af94b5271f33811513b4b7a",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": null,
"timestamp": 1526287186595
}, {
"_id": "5af94b76119abe115ad7aff4",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "111",
"timestamp": 1526287222566
}, {
"_id": "5af94b94119abe115ad7aff5",
"user": "FuRRTBEYBmCSDPJkN",
"post": "5af94b4d71f33811513b4b79",
"text": "1111",
"timestamp": 1526287252138
}]
]
}]
if you have mongodb version 3.6
db.collection.aggregate([
{ "$lookup": {
"from": "post_comments",
"let": { "post_id": "$_id" },
"pipeline": [
{ "$match": {
"$expr": { "$eq": [ "$post", "$$post_id" ] }
}},
{"$sort":{"datetime":-1}},
{"$limit": 3}
],
"as": "three_comments"
}},
{ "$lookup": {
"from":"users",
"localField":"user",
"foreignField":"_id",
"as":"user"
}
}
])

How to check $exists in one to many relationship mongodb sails js?

Is there any way to find records that collection is empty?
For example please find below array. I want only that records with index "companydata" is empty. and also how can i get data that does not have empty "companydata" data.
Thanks in advance.
[
{
"company_id": {
"company_name": "C2",
"slug": "c2",
"is_organized": 1,
"status": "1",
"id": "5adf158f547f7f0314ca8b56",
"companydata": []
},
"user_id": "5ab889aee74a151b50d04ec1",
"status": "0",
"id": "5ae014e7432e85298081be0b"
},
{
"company_id": {
"company_name": "My Compnay",
"slug": "my-compnay",
"is_organized": 1,
"status": "1",
"id": "5ad442d98a0e0c1358ca93df",
"companydata": [
{
"name": "Bhavesh Amin",
"company_id": "5ad442d98a0e0c1358ca93df",
"status": "0",
"id": "5ad442da8a0e0c1358ca93e0"
}
]
},
"user_id": "5ab889aee74a151b50d04ec1",
"status": "0",
"id": "5ae01388432e85298081bdf8"
},
{
"company_id": {
"company_name": "Organization Name",
"slug": "organization-name",
"is_organized": 1,
"status": "1",
"id": "5ad08f9b938d1131eceea624",
"companydata": [
{
"name": "Helen H. Langley",
"company_id": "5ad08f9b938d1131eceea624",
"status": "1",
"id": "5ad08f9b938d1131eceea625"
}
]
},
"user_id": "5ab889aee74a151b50d04ec1",
"status": "0",
"id": "5ad42a5f52851a2b1449db2d"
},
]

How to update a part of an array sub document in MongoDB

I have this document in my mongodb collection:
{
"_id": "YLRM9Wi7f6tp6qNbS",
"sessionId": "hLDkkJKR4Muik6tbe",
"userId": "ZYoG4cH8HcCDPMDGr",
"shopId": "J8Bhq3uTtdgwZx3rz",
"workflow": {
"status": "",
"workflow": ["String"]
},
"billing": [Object],
"discount": 0,
"tax": 0,
"items": [
{
"_id": "JwR233jD2c4HKeYKq",
"shopId": "J8Bhq3uTtdgwZx3rz",
"productId": "BCTMZ6HTxFSppJESk",
"quantity": 1,
"product": {
"_id": "BCTMZ6HTxFSppJESk",
"title": "Product",
"shopId": "J8Bhq3uTtdgwZx3rz",
"ancestors": [],
"createdAt": "2018-01-12T10:22:18.853Z",
"description": "",
"handle": "product",
"hashtags": [
"rpjCvTBGjhBi2xdro",
"cseCBSSrJ3t8HQSNP"
],
"price": {
"range": "12.99 - 19.99",
"min": 12.99,
"max": 19.99
},
"isVisible": true,
"isLowQuantity": false,
"isSoldOut": false,
"isBackorder": false,
"metafields": [
{
"key": "Material",
"value": "Cotton"
},
{
"key": "Quality",
"value": "Excellent"
}
],
"pageTitle": "",
"type": "simple",
"updatedAt": "2018-01-12T10:22:18.854Z",
"vendor": "Vendor_Name",
"originCountry": "country",
"requiresShipping": true,
"isDeleted": false,
"template": "productDetailSimple",
"workflow": {
"status": "new"
}
},
"variants": {},
"title": "Product",
"type": "simple",
"parcel": {
"weight": 25,
"height": 3,
"width": 10,
"length": 10
},
"shippingMethod": {
"shopId": "J8Bhq3uTtdgwZx3rz",
"shipmentQuotes": [Object],
"shipmentQuotesQueryStatus": {
"requestStatus": "success",
"numOfShippingMethodsFound": 11
},
"_id": "s3EJXrLsZe73RbLiD",
"address": {},
"shipmentMethod": {},
"paymentId": "nyybR5BNvDDrJrtwe",
"items": [
{
"_id": "JwR233jD2c4HKeYKq",
"productId": "BCTMZ6HTxFSppJESk",
"shopId": "J8Bhq3uTtdgwZx3rz",
"variantId": "CJoRBm9vRrorc9mxZ"
}
],
"workflow": {
"status": "new",
"workflow": ["String"]
}
},
"workflow": {
"status": "new",
"workflow": ["String"]
}
}
],
"shipping": [Object],
"email": "johndoe#mail.com",
"cartId": "L6sSGv4NR9rpbDbsd",
"createdAt": "2018-01-12T10:22:18.850Z"
}
The field items is an array of objects, I would like to update just a part of the object specifically the workflow field without touching other part of the objects in items array.
I was able to do this using a loop, but it caused some tests to fail. Is there a better of doing this with using a loop?
Thank you.
You can try findAndModify method.
Traverse to the workflow key ad try to set the value.
Hope this would help.

Nested grouping of array

There are 3 master collection of category , subcategory and criteria each, i will be building framework with any possible combination of category , subcategory and criteria which will be stored as below-
framework document is added below having list of criteriaconfig as embedded object which further have single object of category , subcategory and criteria. you can refer criteriaconfig as link table that u call in mysql.
[
{
"id": "592bc3059f3ad715002b2331",
"name": "Framework1",
"description": "framework 1 for testing",
"criteriaConfigs": [
{
"id": "592bc3059f3ad715002b232f",
"category": {
"id": "591c2f5faa187956b2d0fb39",
"name": "category1",
"description": "category1",
"deleted": false,
"createdDate": 1495019359558
},
"subCategory": {
"id": "591c2f5faa187956b2d0fb83",
"name": "subCat1",
"description": "subCat1"
},
"criteria": {
"id": "591c2f5faa187956b2d0fbad",
"name": "criteria1",
"measure": "Action"
}
},
{
"id": "592bc3059f3ad715002b232e",
"category": {
"id": "591c2f5faa187956b2d0fb37",
"name": "Process",
"description": "Enagagement"
},
"subCategory": {
"id": "591c2f5faa187956b2d0fb81",
"name": "COMM / BRANDING",
"description": "COMM / BRANDING"
},
"criteria": {
"id": "591c2f5faa187956b2d0fba9",
"name": "Company representative forgets about customer on hold",
"measure": ""
}
} ]
},
{
"id": "592bc3059f3ad715002b2332",
"name": "Framework2",
"description": "framework 2 for testing",
"criteriaConfigs": [
{
"id": "592bc3059f3ad715002b232f",
"category": {
"id": "591c2f5faa187956b2d0fb39",
"name": "category1",
"description": "category1"
},
"subCategory": {
"id": "591c2f5faa187956b2d0fb83",
"name": "subCat1",
"description": "subCat1"
},
"criteria": {
"id": "591c2f5faa187956b2d0fbad",
"name": "criteria1",
"measure": "Action"
}
}
]
}
]
i need a view containing framework that will contain all list of category and inside category there will be list of added subcategory and inside subcategory will have list of criteria for single framework.
expected result -
[
{
"id": "f1",
"name": "Framework1",
"description": "framework 1 for testing",
"categories": [
{
"id": "c2",
"name": "category2",
"description": "category2",
"subCategories": [
{
"id": "sb1",
"name": "subCat1",
"description": "subCat1",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr2",
"name": "criteria2",
"measure": "Action"
},
{
"id": "cr3",
"name": "criteria3",
"measure": "Action"
}]
},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}]
},
{
"id": "c1",
"name": "category1",
"description": "category1",
"subCategories": [
{
"id": "sb3",
"name": "subCat3",
"description": "subCat3",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr2",
"name": "criteria2",
"measure": "Action"
}
]},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}
]
}]
},
{
"id": "f2",
"name": "Framework2",
"description": "framework 2 for testing",
"categories": [
{
"id": "c2",
"name": "category2",
"description": "category2",
"subCategories": [
{
"id": "sb4",
"name": "subCat5",
"description": "subCat5",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr3",
"name": "criteria3",
"measure": "Action"
}]
},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}]
},
{
"id": "c1",
"name": "category1",
"description": "category1",
"subCategories": [
{
"id": "sb3",
"name": "subCat3",
"description": "subCat3",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr2",
"name": "criteria2",
"measure": "Action"
}
]},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}
]
}]
}
]
Note - Category document doesn't have any reference to subcategory and same way subcategory doesn't have any reference to criteria object currently as they are master data and are generic , framework is created with their combination dynamically.
If you want to try to do all the work in the aggregation, you could group first by subcategory, then by category like:
db.collection.aggregate([
{$unwind:"$criteriaConfigs"},
{$project:{
_id:0,
category:"$criteriaConfigs.category",
subCategory:"$criteriaConfigs.subCategory",
criteria:"$criteriaConfigs.criteria"
}},
{$group:{
_id:{"category":"$category","subCategory":"$subCategory"},
criteria:{$addToSet:"$criteria"}
}},
{$group:{
_id:{"category":"$_id.category"},
subCategories:{$addToSet:{subCategory:"$_id.subCategory",
criteria:"$criteria"}}
}},
{$project:{
_id:0,category:"$_id.category",
subCategories:"$subCategories"
}}
])
Depending on how you plan to us the return data, it may be more efficient to return each unique combination:
db.collection.aggregate([
{$unwind:"$criteriaConfigs"},
{$group:{
_id:{
category:"$criteriaConfigs.category.name",
subCategory:"$criteriaConfigs.subCategory.name",
criteria:"$criteriaConfigs.criteria.name"
}
}},
{$project:{
_id:0,
category:"$_id.category",
subCategory:"$_id.subCategory",
criteria:"$_id.criteria"
}}
])
I'm not sure from your question what shape you are expecting the return data to have, so you may need to adjust for that.