I'm using npm "csv-express" package to export data to CSV. I'm having trouble getting the nested vendor name to display in the exported file. I used the $lookup (aggregation) to get the vendor name from another collection.
Here what the exported file look like:
Here is my query:
db.getCollection('systems').aggregate([
{ "$sort": { "sponsor": 1 } },
{ "$lookup": {
"from": "vendors",
"localField": "vendorID",
"foreignField": "_id",
"as": "vendor"
}
},
{ "$project":{
"sponsor":1,
"address":1,
"city":1,
"state":1,
"vendor.name":1
}
}])
Here's what the query returns:
/* 1 */
{
"_id" : ObjectId("5ab55fee294f2366c054d5eb"),
"sponsor" : "John Doe",
"address" : "123 Western Ave",
"city" : "Los Angeles",
"state" : "CA",
"vendor" : [
{
"name" : "West Interactive"
}
]
}
I tried the following but had no luck.
db.getCollection('systems').aggregate([
{ "$sort": { "sponsor": 1 } },
{ "$lookup": {
"from": "vendors",
"localField": "vendorID",
"foreignField": "_id",
"as": "vendor"
}
},
{ "$project":{
"sponsor":1,
"address":1,
"city":1,
"state":1,
"vendor.[0].name":1
}
}])
Any suggestion would be greatly appreciated!
I found a great article on how to accomplish what I needed.
Here is update query:
db.getCollection('systems').aggregate([
{ "$lookup": {
"from": "vendors",
"localField": "vendorID",
"foreignField": "_id",
"as": "vendor"
}
},
**{ $unwind: "$vendor" },**
{ "$project":{
"sponsor":1,
"address":1,
"city":1,
"state":1,
**"vendorName":"$vendor.name"**
}
}])
This returned the data need for my export.
/* 1 */
{
"_id" : ObjectId("5ab55fee294f2366c054d5eb"),
"sponsor" : "John Doe",
"address" : "123 Western Ave",
"city" : "Los Angeles",
"state" : "CA",
"vendorName" : "Acme Inc."
}
Related
I am new to MongoDB, here I need to form a new table from different collections where it should look like this,
userId userName email phone role
Here according to userId, I need all information from different Collections.
Data:
> db.userinfo.find().pretty()
{
"_id" : ObjectId("56d82612b63f1c31cf906003"),
"userId" : "AD",
"phone" : "0000000000"
}
> db.userrole.find().pretty()
{
"_id" : ObjectId("56d82612b63f1c31cf906003"),
"userId" : "AD",
"role" : "admin"
}
> db.users.find().pretty()
{
"_id" : ObjectId("5684f3c454b1fd6926c324fd"),
"email" : "admin#gmail.com",
"userId" : "AD",
"userName" : "admin"
}
Its a standard lookup to join. Refer $lookup
db.userinfo.aggregate([
{
"$lookup": {
"from": "userrole",
"localField": "userId",
"foreignField": "userId",
"as": "roleJoin"
}
},
{
"$lookup": {
"from": "users",
"localField": "userId",
"foreignField": "userId",
"as": "userJoin"
}
}
])
Working Mongo playground
Hi everyone i have 2 collections named "members" and "offers" in mongoDB. When a member send an offer to another, my web service saves it to offers collection.
"members" collection is like:
[
{
"_id": "5ee00pp0ebfd4432145233344",
"Fname": "John",
"Lname": "Lastname",
"Email": "JohnLastName#gmail.com",
},
{
"_id": "yyyy44p0ebfd4432145233355",
"Fname": "Ashley",
"Lname": "Lastname",
"Email": "AshleyLastName#gmail.com",
},
{
"_id": "yyyy44p0ebfd4432145233355",
"Fname": "Sue",
"Lname": "Lastname",
"Email": "SueLastName#gmail.com",
}
]
when John send an offer to Ashley
"offers" collection is like:
[
{
"_id": "5eea6e62881835271415fd25",
"OfferMail": "JohnLastName#gmail.com",
"Email": "AshleyLastName#gmail.com",
}
]
Now my question is: How can i get all members except Ashley?
Use the $not operator. For example
db.members.find({"Email" : {"$not" : "AshleyLastName#gmail.com"}})
db.members.aggregate([
{
"$lookup": {
"from": "offers",
"localField": "Email",
"foreignField": "Email",
"as": "docuentInB"
}
},
{
$match: {
$expr: { $eq: [{ $size: "$docuentInB" }, 0 ] }
}
},
{
$project: {
docuentInB: 0
}
}
])````
I have one query where I want to group subdocument. i have try some example but it is not working properly
Query
db.getCollection("checklistCombination").aggregate([
{
"$lookup": {
"from": "Users",
"localField": "userId",
"foreignField": "_id",
"as": "user"
}
},
{
"$lookup": {
"from": "checklist",
"localField": "checklistId",
"foreignField": "_id",
"as": "linkChecklist"
}
},
{ "$unwind": "$linkChecklist" },
{
"$lookup": {
"from": "orderDetail",
"localField": "linkChecklist.product",
"foreignField": "productRangeId",
"as": "orderProduct"
}
},
{
"$unwind": { "path": "$orderProduct", "preserveNullAndEmptyArrays": true }
},
{
"$lookup": {
"from": "companysuppliers",
"localField": "orderProduct.supplierId",
"foreignField": "_id",
"as": "comapnySupplier"
}
},
{
"$unwind": {
"path": "$comapnySupplier",
"preserveNullAndEmptyArrays": true
}
},
{
"$lookup": {
"from": "suppliers",
"localField": "comapnySupplier.supplierId",
"foreignField": "_id",
"as": "supplier"
}
},
{ "$unwind": { "path": "$supplier", "preserveNullAndEmptyArrays": true } },
{
"$project": {
"_id": 1,
"name": 1,
"user": 1,
"linkChecklist": 1,
"orderProduct": 1,
"orderProductStatusIndex": {
"$ifNull": ["$orderProduct.statusIndex", "0"]
},
"comapnySupplier": 1,
"supplier": 1
}
},
{ "$match": { "orderProductStatusIndex": "0" } },
{
"$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"supplier": {
"$push": {
"supplierId": "$supplier._id",
"supplierName": "$supplier.name",
"items": { "$sum": "$orderProduct.quantity" }
}
}
}
}
])
This query return below result
[{
"_id" : ObjectId("5cee224b97e765079c8c2839"),
"name" : "Dairy",
"supplier" : [
{
"supplierId" : ObjectId("5cee12a7a01ad50f5c2229ac"),
"supplierName" : "Bhagwandas Bherumal",
"items" : 10
}
]
},
{
"_id" : ObjectId("5cee1a19a01ad50f5c2229f2"),
"name" : "dairy/fruit",
"supplier" : [
{
"supplierId" : ObjectId("5cee12a7a01ad50f5c2229ac"),
"supplierName" : "Bhagwandas Bherumal",
"items" : 55
},
{
"supplierId" : ObjectId("5cee11f7a01ad50f5c2229a2"),
"supplierName" : "Agron India PVT. LTD",
"items" : 55
},
{
"supplierId" : ObjectId("5cee12a7a01ad50f5c2229ac"),
"supplierName" : "Bhagwandas Bherumal",
"items" : 10
}
]
}]
In result you can see there are two different results for Bhagwandas Bherumal in dairy/fruit (in array index 1 ). I want to group by this field and sum its items.
Expected Result
[
{
"_id" : ObjectId("5cee224b97e765079c8c2839"),
"name" : "Dairy",
"supplier" : [
{
"supplierId" : ObjectId("5cee12a7a01ad50f5c2229ac"),
"supplierName" : "Bhagwandas Bherumal",
"items" : 10
}
]
},
{
"_id" : ObjectId("5cee1a19a01ad50f5c2229f2"),
"name" : "dairy/fruit",
"supplier" : [
{
"supplierId" : ObjectId("5cee12a7a01ad50f5c2229ac"),
"supplierName" : "Bhagwandas Bherumal",
"items" : 65
},
{
"supplierId" : ObjectId("5cee11f7a01ad50f5c2229a2"),
"supplierName" : "Agron India PVT. LTD",
"items" : 55
}
]
}]
Hope this solves your problem :
db.getCollection("checklistCombination").aggregate([
{
"$lookup": {
"from": "Users",
"localField": "userId",
"foreignField": "_id",
"as": "user"
}
},
{
"$lookup": {
"from": "checklist",
"localField": "checklistId",
"foreignField": "_id",
"as": "linkChecklist"
}
},
{ "$unwind": "$linkChecklist" },
{
"$lookup": {
"from": "orderDetail",
"localField": "linkChecklist.product",
"foreignField": "productRangeId",
"as": "orderProduct"
}
},
{
"$unwind": { "path": "$orderProduct", "preserveNullAndEmptyArrays": true }
},
{
"$lookup": {
"from": "companysuppliers",
"localField": "orderProduct.supplierId",
"foreignField": "_id",
"as": "comapnySupplier"
}
},
{
"$unwind": {
"path": "$comapnySupplier",
"preserveNullAndEmptyArrays": true
}
},
{
"$lookup": {
"from": "suppliers",
"localField": "comapnySupplier.supplierId",
"foreignField": "_id",
"as": "supplier"
}
},
{ "$unwind": { "path": "$supplier", "preserveNullAndEmptyArrays": true } },
{
"$project": {
"_id": 1,
"name": 1,
"user": 1,
"linkChecklist": 1,
"orderProduct": 1,
"orderProductStatusIndex": {
"$ifNull": ["$orderProduct.statusIndex", "0"]
},
"comapnySupplier": 1,
"supplier": 1
}
},
{ "$match": { "orderProductStatusIndex": "0" } },
{ $group : {
_id : {
_id : '$_id',
name : '$name',
supplierId : "$supplier._id",
supplierName : "$supplier.name"
},
items : { "$sum": "$orderProduct.quantity"}
}
},
{
$group : {
_id : '$_id._id',
name : { "$first": "$_id.name" },
supplier : {
"$push": {
"supplierId": "$_id.supplierId",
"supplierName": "$_id.supplierName",
"items" : '$items'
}
}
}
}
])
How can i perform $lookup in aggregate (mongodb) for an array
{
messages: [{
"_id" : ObjectId("5bfc43f2bbc4176ecc1c5f83"),
"text" : "text1",
"sender" : {
"id" : "36046fc2e70dd508a0bf1f36fd2daa20"
}
}, {
"_id" : ObjectId("5bfc43f2bbc4176ecc1c5f83"),
"text" : "text2",
"sender" : {
"id" : "36046fc2e70dd508a0bf1f36fd2daa22"
}
}],
"filed1": { ... },
"filed2": { ... }
}
how can i do a $lookup for sender id from accounts collection?
tried:
...
{
$lookup: {
from: "accounts",
localField: "messages.sender.id",
foreignField: "id",
as: "messages.sender.user"
}
}
...
You can use below aggregation
db.collection.aggregate([
{ "$unwind": "$messages" },
{ "$lookup": {
"from": "accounts",
"localField": "messages.sender.id",
"foreignField": "id",
"as": "messages.sender.user"
}},
{ "$unwind": "$messages.sender.user" }
{ "$group": {
"_id": "$_id",
"messages": { "$push": "$messages" },
"filed1": { "$first": "$filed1" },
"filed2": { "$first": "$filed2" }
}}
])
I m stuck with a mongo aggregate query. Right now I have a collection which contains posts of various users (whose details are present in users collection).
I need a query to fetch only one post of each user (like group by in SQL)
POSTS collection data
{
language:'english',
status:'A',
desc:'Hi there',
userId:'5b891370f43fe3302bbd8918'
},{
language:'english',
status:'A',
desc:'Hi there - 2'
userId:'5b891370f43fe3302bbd8918'
},{
language:'english',
status:'A',
desc:'Hi there - 3'
userId:'5b891370f43fe3302bbd8001'
}
Here is my query
db.col('posts').aggregate([
{
$match: {
language: 'english',
status: "A"
}
}, {
$sample: { size: 10 }
}, {
$sort: { _id: -1 }
}, {
$lookup: {
from: 'users',
localField: 'userId',
foreignField: '_id',
as: 'ownerData'
}
}], (err, data) => { console.log(err,data) });
Desired Output
{
language:'english',
status:'A',
desc:'Hi there',
userId:'5b891370f43fe3302bbd8918',
ownerData:[[object]]
},{
language:'english',
status:'A',
desc:'Hi there - 3'
userId:'5b891370f43fe3302bbd8001',
ownerData:[[object]]
}
$group: will as group by of mysql. $first: will take first element of collection field from group. $lookup acts as join in mysql.
db.tempdate.aggregate([
{ $group :
{
_id : "$userId",
language : { $first: '$language' },
status : { $first: '$status' },
desc : { $first: '$desc' }
}
},
{ $lookup:
{
from: "user",
localField: "_id",
foreignField: "user_id",
as: "userData"
}
}
]).pretty();`
Output
`{
"_id" : "5b891370f43fe3302bbd8001",
"language" : "english",
"status" : "A",
"desc" : "Hi there - 3",
"userData" : [
{
"_id" : ObjectId("5ba3633a12b8613823f3056e"),
"user_id" : "5b891370f43fe3302bbd8001",
"name" : "Bhuwan"
}
]
}
{
"_id" : "5b891370f43fe3302bbd8918",
"language" : "english",
"status" : "A",
"desc" : "Hi there",
"userData" : [
{
"_id" : ObjectId("5ba3634612b8613823f3056f"),
"user_id" : "5b891370f43fe3302bbd8918",
"name" : "Harry"
}
]
}
Also, you can use group and $last
db.getCollection('posts').aggregate([
{ "$match": { "language": 'english', "status": "A" }},
{ "$group": {
"_id": "$userId",
"primaryId" : { "$last": "$_id" },
"language": { "$last": "$language" },
"status": { "$last": "$status" },
"desc": { "$last": "$desc" }
}},
{ "$lookup": {
"from": "users",
"localField": "_id",
"foreignField": "_id",
"as": "ownerData"
}},
{ $unwind:{path: '$ownerData',preserveNullAndEmptyArrays: true} //to convert ownerData to json object
}
])
You can use $group aggregation stage for the distinct userId and then use $lookup to get users data.
db.col('posts').aggregate([
{ "$match": { "language": 'english', "status": "A" }},
{ "$sample": { "size": 10 }},
{ "$sort": { "_id": -1 }},
{ "$group": {
"_id": "$userId",
"language": { "$first": "$language" },
"status": { "$first": "$status" },
"desc": { "$first": "$desc" }
}},
{ "$lookup": {
"from": "users",
"localField": "_id",
"foreignField": "_id",
"as": "ownerData"
}}
])