am trying to aggregate values of multiple documents in one, but unable to do it,
db.doc1.find().pretty();
{
"addressId" : ObjectId("5901a5f83541b7d5d3293768"),
"socialId" : ObjectId("5901b0f6d318b072ceea44fb")
}
db.doc2.find().pretty();
{
"_id" : ObjectId("5901a5f83541b7d5d3293768"),
"address" : "Gurgaon",
"mob" : "9876543211"
}
db.doc3.find().pretty();
{
"_id" : ObjectId("5901b0f6d318b072ceea44fb"),
"fbURLs" : "http://www.facebook.com",
"twitterURLs" : "http://www.twitter.com"
}
My Query
db.doc2.aggregate([
{ $match: { "_id" : ObjectId("5901a5f83541b7d5d3293768") } },
{
$lookup:
{
from: "doc1",
localField: "_id",
foreignField: "addressId",
as: "Doc2Details"
}
}
]).pretty();
db.doc3.aggregate([
{ $match: { "_id" : ObjectId("5901b0f6d318b072ceea44fb") } },
{
$lookup:
{
from: "doc1",
localField: "_id",
foreignField: "socialId",
as: "tireConfig"
}
}
]).pretty();
I want match values from Doc1 and combine values of doc2 and doc3, can someone help me with this?
Related
Im trying to populate the second nested array after using aggregate $lookup.
This is my original array.
{
"_id" : ObjectId("607da9c0c7cb26384c7810a6"),
"date" : ISODate("2021-04-20T00:00:00.000+0000"),
"clientID" : "601e6dc61766587af8ce76db",
"medications" : [
{
"_id" : ObjectId("6065de3aa95e721f587f7528")
},
]
}
{
from: "medications",
localField: "medications._id",
foreignField: "_id",
as: "medications",
}
after using aggregate $lookup I get this result, but I still have nested array "inventory" that I need to populate. I tried adding another $lookup pipeline, but I don't know how the right way to do that.
{
"_id" : ObjectId("607da9c0c7cb26384c7810a6"),
"date" : ISODate("2021-04-20T00:00:00.000+0000"),
"clientID" : "601e6dc61766587af8ce76db",
"medications" : {
"_id" : ObjectId("6065de3aa95e721f587f7528"),
"medication": "med 1"
"schedule": ["9am", "10pm"]
"inventory": "ObjectId("6076d55ab6aeb947dca85877")"
}
}
This is the inventory item
{
"_id" : ObjectId("6076d55ab6aeb947dca85877"),
"item": "Inventory item 1",
"Qty": "10"
}
Expected Output
{
"_id" : ObjectId("607da9c0c7cb26384c7810a6"),
"date" : ISODate("2021-04-20T00:00:00.000+0000"),
"clientID" : "601e6dc61766587af8ce76db",
"medications" : {
"_id" : ObjectId("6065de3aa95e721f587f7528"),
"medication": "med 1"
"schedule": ["9am", "10pm"]
"inventory": {
"_id" : ObjectId("6076d55ab6aeb947dca85877"),
"item": "Inventory item 1",
"Qty": "10"
}
}
}
You can try this one or alternatively use population.
{
from: "medications",
localField: "medications._id",
foreignField: "_id",
as: "medications",
}
, {
$unwind: {
path: "$medications",
preserveNullAndEmptyArrays: true
}
}, {
$lookup: {
from: "inventory",
localField: "inventory._id",
foreignField: "_id",
as: "medications.inventory",
}
}
You may check the $unwind in the official documentation. Just pay attention to the appropriate localField and foreignField.
use populate() to expand nested references.
schemaModel.populate(result, {path: 'result'});
See more at Mongoose docs
I have three collections in EmployeeDB.
Employee
{
"user_id" : "EMP001",
"FirstName" : "Manoj",
"LastName" : "sharma",
"Status" : "0/1",
"CreateDate" : "1988-10-11T18:30:00.000Z"
}
EmpContact
{
"user_id" : "EMP001",
"Phone" : "9999999999",
"Email" : "xyz#gmail.com"
}
EmpInfo
{
"user_id" : "EMP001",
"Gender" : "Male",
"Age" : NumberInt(20),
"Designation" : "manager",
"Salary" : "5000"
}
I need to group the three collections and display all fields.
I tried the below code,
db.Employee.aggregate([
{$lookup: {from: "EmpContact",localField: "user_id",foreignField: "user_id",as: "contact"}},
{$unwind:"$EmpContact"},
{$lookup: {from: "EmpInfo",localField: "user_id",foreignField: "user_id",as: "empinfo"}},
{$unwind:"$EmpInfo"},
{
$match:{user_id : "EMP001"}
}
]).toArray();
But I got an empty array, Please help me...
The problem comes from your $unwind.
Since you name your field as contact in the $lookup, the field EmpContact doesn't exist.
The same thing for the second unwind, EmpInfo doesn't exist but empinfo does
Here is the full query
db.Employee.aggregate([
{
$lookup: {
from: "EmpContact",
localField: "user_id",
foreignField: "user_id",
as: "contact"
}
},
{
$unwind: "$contact"
},
{
$lookup: {
from: "EmpContact",
localField: "user_id",
foreignField: "user_id",
as: "empinfo"
}
},
{
$unwind: "$empinfo"
},
{
$match: {
user_id: "EMP001"
}
}
])
Try it here
I have the following aggregate query:
db.getCollection('village').aggregate([
{
"$match": { _id: "111" }
},
{
"$lookup": {
from: "character",
localField: "chieftainId",
foreignField: "_id",
as: "chieftain"
},
"$lookup": {
from: "character",
localField: "villagerIds",
foreignField: "_id",
as: "villager"
}
},
{ "$project" : { "villagerIds" : 0}}
])
And this is its result:
{
"_id" : "111",
"name" : "MyVillage",
"chieftainId" : "222",
"reputation" : 0,
"villagers" : [
{
"_id" : "333",
"name" : "Bortan",
"age" : 21,
"bloodlineId" : "7f02191f-90af-406e-87ff-41d5b4387999",
"villageId" : "foovillage",
"professionId" : "02cbb10a-6c0f-4249-a932-3f40e12d32c5"
},
{
"_id" : "444",
"name" : "Blendi",
"age" : 21,
"bloodlineId" : "b3a8ffeb-27aa-4e2e-a8e6-b382554f326a",
"villageId" : "foovillage",
"professionId" : "45dc9350-c84a-491d-a49a-524834dd5773"
}
]
}
As you can see villagerIds has been resolved to villagers. However chieftainId has not been resolved to chieftain. When I omit the second $lookup (with villager) then chieftain is being resolved successfully. It seems that only one $lookup will be effective and not both. Any idea how I can make both work?
Use separate pipeline for both $lookup
db.getCollection('village').aggregate([
{
"$match": { _id: "111" }
},
{
"$lookup": {
from: "character",
localField: "chieftainId",
foreignField: "_id",
as: "chieftain"
}
},
{
"$lookup": {
from: "character",
localField: "villagerIds",
foreignField: "_id",
as: "villager"
}
},
{ "$project" : { "villagerIds" : 0}}
])
I have below two collections
db.sample.find().pretty()
{
"_id" : ObjectId("5930093eb3aaa7c02d4cbcdc"),
"name" : "Ashish",
"posts" : [
{
"_id" : ObjectId("59301c39028afaf3450e2444"),
"post" : ObjectId("59301c39028afaf3450e2885")
},
{
"_id" : ObjectId("59301c39028afaf3450e2445"),
"post" : ObjectId("59301c39028afaf3450e2889")
}
]
}
and other one
db.posts.find().pretty()
{ "_id" : ObjectId("59301c39028afaf3450e2885"), "title" : "test1" }
{ "_id" : ObjectId("59301c50028afaf3450e2889"), "title" : "test2" }
I want to join these two based on matching posts._id & sample.post._id value.
& create structure showing "Title" value as below:
In short create structure which shows post liked by each user.
"name" : "Ashish",
"posts" : [
{
"post" : ObjectId("59301c39028afaf3450e2889"),
"title" :"test2"
},
{
"post" : ObjectId("59301c39028afaf3450e2885"),
"title" :"test1"
},
we can join two collection using $lookup some thing like this
db.sample.aggregate([
{
$lookup:
{
from: "posts",
localField: "posts.post",
foreignField: "_id",
as: "samplepost"
}
}
])
https://docs.mongodb.com/v3.2/reference/operator/aggregation/lookup/
You can test it
db.sample.aggregate([
{$unwind: "$posts"},
{
$lookup: {
from: "posts",
localField: "posts.post",
foreignField: "_id",
as: "post"
}
},
{
$group: {
_id: "$_id",
name: {$first: "$name"},
posts: {
$push: {
post: {$arrayElemAt: ["$post._id", 0]},
title: {$arrayElemAt: ["$post.title", 0]}
}
}
}
}
])
Three collections Product, ProductDescription, Language like this:
> db.Language.find();
{
"_id" : ObjectId("1234..."),
"isoCc" : "EN"
}
{
"_id" : ObjectId("5678..."),
"isoCc" : "DE"
}
> db.Product.find();
{
"_id" : ObjectId("3eff..."),
"sku" : "123456",
"title" : "Some Product Title"
}
> db.ProductDescription.find();
{
"_id" : ObjectId("44ad..."),
"ofProduct" : ObjectId("3eff..."),
"ofLanguage" : ObjectId("1234..."),
"shortDescription" : "English description"
}
{
"_id" : ObjectId("f5aa..."),
"ofProduct" : ObjectId("3eff..."),
"ofLanguage" : ObjectId("5678..."),
"shortDescription" : "German description"
}
If I do a lookup on the ProductDescription like this
db.Product.aggregate([
{
$lookup:
{
from: "ProductDescription",
localField: "_id",
foreignField: "ofProduct",
as: "description"
}
}
])
I get both entrys of ProductDescription.
So how can I also filter what language the description should be?
If you want to lookup description language also then you need to use another lookup for description.ofLanguage
db.Product.aggregate([
{
$lookup:
{
from: "ProductDescription",
localField: "_id",
foreignField: "ofProduct",
as: "description"
}
},
{
$lookup:
{
from: "Language",
localField: "description.ofLanguage",
foreignField: "_id",
as: "language"
}
}
])