Facing a problem for retrieving nested collection data using Mongodb query - node.js

I have a three collections, names are "Category", "Subcategory" and "Services". I have tried an aggregate query but I am not able to populate desired result.
I need output as below.
https://www.screenpresso.com/=4LBTc
I have tried the below query
PlumbingList:async(req,res)=>{
const result=await Categoriesmodel.
find()
.aggregate([
{$lookup:{from:"subCategory",localField:"_id",foreignField:"SubCategoryId",as:"sub_category"}},
{$lookup:{from:"Services",localField:"_id",foreignField:"Services_id",as:"service_list"}}
]);
res.json({message:"categories list",result})
}
Can anyone let me know where I am wrong?

const sync = async (req, res) => {
const result = await Categoriesmodel.aggregate([
{
$lookup: {
from: "subCategory",
localField: "SubCategoryId",
foreignField: "_id",
as: "sub_category",
},
},
{
$lookup: {
from: "Services",
localField: "Services_id",
foreignField: "_id",
as: "service_list",
},
},
]);
res.json({ message: "categories list", result });
};

Related

NodeJs mongoose performance slow when compared with mongo shell or robo3t performance

I am running a query that prints around 300 results using aggregate.
The query is super fast when executed in robo3t/mongo shell but super slow when done using mongoose in NodeJs.
Tried finding for an answer, landed on this link tried setting DBQuery.shellBatchSize = 500000; but difference b/w two queries is still around 7-8 secs
Also, updated the mongoose and mongodb version to the latest one today itself.
here is the query:
db.getCollection('fixed_activities').aggregate([
{
$lookup: {
from: "city",
localField: "activity_city",
foreignField: "_id",
as: "activity_location"
}
},
{
$lookup: {
from: "rate_sheet_activity_prices",
localField: "_id",
foreignField: "act_id",
as: "rate_sheets"
}
},
{
$lookup: {
from: "organizations",
localField: "rate_sheets.rate_sheet_id",
foreignField: "rate_sheets.rate_sheet_id",
as: "org_id"
}
},
{
$lookup: {
from: "images",
localField: "activity_image",
foreignField: "_id",
as: "activity_image"
}
},
{ $match: { org_id: { $exists: true, $not: { $size: 0 } } } }
])
I had the same problem, my solution was to switch from mongoose to the native mongodb controller in nodejs.
https://mongodb.github.io/node-mongodb-native/3.3/installation-guide/installation-guide/

Mongoose compare with a third level nested field value

I have the following collections:
and I would like to do a find from collection1 all the way to collection 3 and 4 to compare name in one query.
example:
collection1.find({
collection2.collection3.name: req.body.name3,
collection2.collection4.name: req.body.name4
}).exec()
You need to use lookup, unwind and match, here is untested solution of your problem
Model.aggregate([
{
$match: {
_id: req.params.id
// for object id use
// _id: mongoose.Types.ObjectId(req.params.id)
}
},
{
$lookup: {
from: "collection2",
localField: "collection2",
foreignField: "_id",
as: "Collection2"
}
},
{
$unwind: "$ColelctionTwo"
},
{
$lookup: {
from: "collection3",
localField: "CollectionTwo.collection3",
foreignField: "_id",
as: "Collection3"
}
},
{
$lookup: {
from: "collection4",
localField: "CollectionTwo.collection4",
foreignField: "_id",
as: "Collection4"
}
}
]).exec(function(err, result) {
if(err) {
// handle here
}
if(result) {
// do something here...
}
}
You can use mongodb aggregate framework's $lookup or $graphlookup stages for multi collection queries. Mongoose docs for aggregation https://mongoosejs.com/docs/api.html#Aggregate
You cannot do a simple find query for multi collection lookups.

mongo db select all rows fom 2 tables based on the join condition

I have 2 tables
useraverage
id
average
usersdetails
id
name
address
output
id
name
address
average
i have tried lookup but its not returning the data.
db.userdetails.aggregate([
{
$lookup:
{
from: "useraverage",
localField: "id",
foreignField: "id",
as: "useraverage"
}
}
],function (err, result) {
console.log(result);
res.json(result);
});
Are you using MongoDB's _id or you own ? If you're using the first option then you query should look like this :
`db.userdetails.aggregate([
{
$lookup:
{
from: "useraverage",
localField: "_id",
foreignField: "_id",
as: "useraverage"
}
},
{$unwind : "$useraverage"},
{$project : {
name : 1,
address : 1,
average: "$useraverage.average"
}}
],function (err, result) {
console.log(result);
res.json(result);
});`

Getting Mongoose Error: Arguments must be aggregate pipeline operators

I'm trying to run this aggregations but I cannot get a result with aggregation option parameter, what is wrong ? Here is my aggregation:
var coupons = couponModel.aggregate(
[
{
"$lookup": {
from: "campaigns",
localField: "campaignId",
foreignField: "_id",
as: "campaigns"
}
},
{ "campaignId": { "$in": campaignsIds } },
],
{
allowDiskUse: true,
explain: true
}
);
Also Try Different Structure:
couponModel.aggregate(
[
{
"$lookup": {
from: "campaigns",
localField: "campaignId",
foreignField: "_id",
as: "campaigns"
}
},
{ "campaignId": { "$in": campaignsIds } },
],
function(err,result) {
if (err) return handleError(err);
// Result is an array of documents
console.log(result);
}
)
When using mongoose you cannot pass an object as the second parameter of aggregate(). Instead you must use mongoose functions. Also, in the second object of your pipeline you forgot to specify the aggregation stage. So your code would look like this:
var coupons = couponModel.aggregate(
[
{
"$lookup": {
from: "campaigns",
localField: "campaignId",
foreignField: "_id",
as: "campaigns"
}
},
{ $match: { "campaignId": { "$in": campaignsIds } } }
]
)
.allowDiskUse(true)
.explain(true);

why does my aggregate ($lookup) function does not work in mongoose and node.js?

In my mongoose database I have two models: Users and Comments.
In my node.js code I have:
var Comment = require('./../models/commentsModel.js');
var User = require('./../models/usersModel.js');
Now I want to construct a query with $lookup to return results from Comments and corresponding Users (currently Comments contain a field user_id). This is what I have so far:
function executeQuery(query, callback) {
query = Comment.find(query);
Comment.aggregate([{$lookup:
{ from: "users",
localField: "user_id",
foreignField:"_id",
as: "user"
}}]);
query.exec(function(err, comments){
if(err) {
callback(err);
return;
}
return callback(null, comments);
});
}
but I do not see any data from User attached to the results from Comment. What am I missing?
You are not executing your aggregation query. Either add a function callback at the end or call exec(function(err,res)) :
Comment.aggregate([{
$lookup: {
from: "users",
localField: "user_id",
foreignField: "_id",
as: "user"
}
}],function(err,res){
console.log(res);
});
Or
var aggregateQuery = Comment.aggregate([{
$lookup: {
from: "users",
localField: "user_id",
foreignField: "_id",
as: "user"
}
}]);
aggregateQuery.exec(function(err,res){
console.log(res);
})

Resources