Using node.js, I want to define a route in which for four different categories MongoDB is queried and two documents for each category are returned. The response of the route should thus be an array of four arrays which contain two documents each.
I wrote this code:
router.get("/sample9/all", (req, res) => {
console.log("Call to 9 route was made");
clusters = ["icecream", "chocolate"];
newData = []
clusterFood = clusters.map(cluster =>
dbase
.db("course1")
.collection("food")
.find({ category: cluster })
.limit(2)
.toArray((err, results) => {
newData.push(results);
})
);
res.send(clusters);
});
This gives a response with an empty object. Could anybody help? I am just getting started with node.js and MongoDB.
You can use aggregation framework for this type of query. Your pipeline comprises of an initial $match
stage which filters the collection on the 4 categories passed.
The preceding pipeline stage will be the $group
step which then groups the filtered input documents by the category field, create an array with the top level documents from each group and a final pipeline $project
stage that reshapes the array to just include two documents using $slice
.
Consider running the following pipeline to get the desired result:
Main pipeline:
const pipeline = [
{ '$match': {
'category': { '$in': clusters }
} },
{ '$group': {
'_id': '$category',
'docs': { '$push': '$$ROOT' }
} },
{ '$project': {
'docs': { '$slice': ['$docs', 2] }
} }
];
Using aync/await
router.get("/sample9/all", async (req, res) => {
console.log("Call to 9 route was made");
const collection = dbase.db("course1").collection("food");
const results = await collection.aggregate(pipeline).toArray();
res.send(results);
});
Using Promises
router.get("/sample9/all", (req, res) => {
console.log("Call to 9 route was made");
const collection = dbase.db("course1").collection("food");
const agg = collection.aggregate(pipeline);
agg.then(results => res.send(results))
.catch(err => console.error(err));
});
Using callbacks
router.get("/sample9/all", (req, res) => {
console.log("Call to 9 route was made");
const collection = dbase.db("course1").collection("food");
collection.aggregate(pipeline).toArray((err, results) => {
if (err) {
console.error(err);
}
else {
res.send(results)
}
});
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.