Given two collections users and activities, I want to enrich users.friends.user with all relevant activities, such that users.friends.user matches doc2.invitations.userId.
Below describes exactly what I would like:
user f24b189f-9e00-4d2b-b7f2-148a265fae7c is not a part of any activity, so their activities array is [].
user 223f2e04-6f0c-40a3-a88a-69d0127f2e92 is a part of an activity, so their activities array is populated with the activity object.
Raw:
db={
"users": [
{
"_id": "9c69a57f-e90a-43be-b559-449e973c6cba",
"__v": {
"$numberInt": "0"
},
"friends": [
{
"status": "ACCEPTED",
"user": "f24b189f-9e00-4d2b-b7f2-148a265fae7c"
},
{
"status": "ACCEPTED",
"user": "223f2e04-6f0c-40a3-a88a-69d0127f2e92"
}
]
}
],
"activities": [
{
"_id": {
"$oid": "63a92531bc6dea668f93bb06"
},
"invitations": [
{
"_id": {
"$oid": "63a92531bc6dea668f93bb07"
},
"userId": "9c69a57f-e90a-43be-b559-449e973c6cba",
"status": "ACCEPTED"
},
{
"_id": {
"$oid": "63a92544bc6dea668f93bb09"
},
"userId": "223f2e04-6f0c-40a3-a88a-69d0127f2e92",
"status": "ACCEPTED"
},
],
"__v": {
"$numberInt": "0"
}
}
]
}
Expected result:
"expectedResult": [
{
"_id": "9c69a57f-e90a-43be-b559-449e973c6cba",
"__v": {
"$numberInt": "0"
},
"friends": [
{
"status": "ACCEPTED",
"activities": [{
"_id": {
"$oid": "63a92531bc6dea668f93bb06"
},
"invitations": [
{
"_id": {
"$oid": "63a92531bc6dea668f93bb07"
},
"userId": "9c69a57f-e90a-43be-b559-449e973c6cba",
"status": "ACCEPTED"
},
{
"_id": {
"$oid": "63a92544bc6dea668f93bb09"
},
"userId": "223f2e04-6f0c-40a3-a88a-69d0127f2e92",
"status": "ACCEPTED"
},
],
"__v": {
"$numberInt": "0"
}
}]
},
{
"status": "ACCEPTED",
"activities": []
}
]
}
]
And here's a link to the playground.
I played around with aggregate and populate, but this use case is unlike a regular "join", which is throwing me off. Any pointers will be appreciated.
In my application, I have a section of comments and replies under some documents.
Here's how my database schema looks like
db.updates.insertOne({
"_id": "62347813d28412ffd82b551d",
"documentID": "17987e64-f848-40f3-817e-98adfd9f4ecd",
"stream": [
{
"id": "623478134c449b218b68f636",
"type": "comment",
"text": "Hey #john, we got a problem",
"authorID": "843df3dbbdfc62ba2d902326",
"taggedUsers": [
"623209d2ab26cfdbbd3fd348"
],
"replies": [
{
"id": "623478284c449b218b68f637",
"type": "reply",
"text": "Not sure, let's involve #jim here",
"authorID": "623209d2ab26cfdbbd3fd348",
"taggedUsers": [
"26cfdbbd3fd349623209d2ab"
]
}
]
}
]
})
db.users.insertMany([
{
"_id": "843df3dbbdfc62ba2d902326",
"name": "Manager"
},
{
"_id": "623209d2ab26cfdbbd3fd348",
"name": "John"
},
{
"_id": "26cfdbbd3fd349623209d2ab",
"name": "Jim"
},
])
I want to join those two collections, and replace user ids with complete user information on all levels. So the final JSON should look like this
{
"_id": "62347813d28412ffd82b551d",
"documentID": "17987e64-f848-40f3-817e-98adfd9f4ecd",
"stream": [
{
"id": "623478134c449b218b68f636",
"type": "comment",
"text": "Hey #john, we got a problem",
"author": {
"_id": "843df3dbbdfc62ba2d902326",
"name": "Manager"
},
"taggedUsers": [
{
"_id": "623209d2ab26cfdbbd3fd348",
"name": "John"
}
],
"replies": [
{
"id": "623478284c449b218b68f637",
"type": "reply",
"text": "Not sure, let's involve #jim here",
"author": {
"_id": "623209d2ab26cfdbbd3fd348",
"name": "John"
},
"taggedUsers": [
{
"_id": "26cfdbbd3fd349623209d2ab",
"name": "Jim"
}
]
}
]
}
]
}
I know how to do the $lookup on the top-level fields, including pipelines, but how can I do with the nested ones?
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.
Example: A Collection name is Account which is having categories and upvotes and downvotes. Upvotes and downvotes are basically feeds of categories. The structure of the Collection is as follows:
{
"id": "585a2f2735cc577c178bda2b",
"category_ids": [
"5857e65c950cfd241818abc3",
"5857e92f950cfd241818abd0",
"5857e957950cfd241818abd2",
"5857f03f950cfd241818abd5"
],
"upVotes": [
{
"id": "585a6ccc055f93cbb10bd179",
"name": "career feed",
"category_ids": [
"5857e65c950cfd241818abc3"
]
},
{
"id": "5860bc714b7b3a400ef96d2a",
"name": "Treasurers and Controllers",
"category_ids": [
"5857e957950cfd241818abd2"
]
}
],
"downVotes": [
{
"id": "585a8fbb416ecf300c6ea969",
"name": "testinggggg",
"category_ids": [
"5857f03f950cfd241818abd5",
"5857f07c950cfd241818abd6"
]
},
{
"id": "585a8406354db7d811f9a405",
"name": "feeds5",
"category_ids": [
"5857e957950cfd241818abd2",
"5857f07c950cfd241818abd6"
]
}
]
}
I want to show downvotes and upvotes according to the category of user.
[Working on Mongo DB]
OUTPUT:
"Category": [{
"id": "585a6ccc055f93cbb10bd179",
"upvotes": [{
"id": "",
"name": ""
}, {
"id": "",
"name": ""
}],
"downvotes": [{
"id": "",
"name": ""
}, {
"id": "",
"name": ""
}]
}]
I am working on mongoDB with Laravel using jenssegers . and i am trying to get
documents on sorting based on layout.price.
Is this possible in mongodb with laravel. ?
I am using limit and skip for pagination , so i have to get orderBy or sort direct from Database.
[{
"title": "I am first document",
"design": "mango",
"description": "Loremipsum",
"dimension": [
{
"id": "542549383d1784901000002c"
}
],
"layout": [
{
"id": "542411813d17849810000029",
"price": NumberInt(69000)
}, {
"id": "542411813d17849810000030",
"price": NumberInt(2000)
}
],
"images": [
"uploads/sofa/QRSTU695a6_0.png"
],
"product_type": NumberInt(1),
"updated_at": ISODate("2014-10-08T08:47:26.0Z"),
"created_at": ISODate("2014-09-29T11:13:52.0Z")
},
{
"title": "I am second document",
"design": "mango2",
"description": "Loremipsum",
"dimension": [
{
"id": "542549383d1784901000002d"
}
],
"layout": [
{
"id": "542411813d17849810000031",
"price": NumberInt(80000)
}, {
"id": "542411813d17849810000032",
"price": NumberInt(27000)
}
],
"images": [
"uploads/sofa/QRSTU695a6_0.png"
],
"product_type": NumberInt(1),
"updated_at": ISODate("2014-10-08T08:47:26.0Z"),
"created_at": ISODate("2014-09-29T11:13:52.0Z")
}]