Limit fields in MongoDB response - node.js

I am doing a join using $lookup, but I'm getting all the field, including those which are not required, so i need to restrict it.
Here is my query
exports.query = function (req, res) {
QuestionList.aggregate([{
$match : {
topicName : req.query.topicName
}
}, {
$lookup : {
from : "questions",
localField : "quesList.quesListName",
foreignField : "quesListName",
as : "quesListCount"
}
}
], {
quesList : 0
}, function (err, questionList) {
console.log(questionList);
if (err) {
return handleError(res, err);
}
return res.status(200).json(fnData(questionList));
});
};
the response I am getting is
{
_id : "57453e45a11c97483f97a4c9",
quesList : {
by : "swathi",
quesListName : "Controller Question List",
quesListCount : [{
quesListName : "Controller Question List",
question : "What is a Controller function?"
}
]
},
}
here I need to restrict quesListName in quesListCount array .

Related

how to delete item from nested array of objects in mongoose

This is how my "Users" databse looks like:
{
"_id" : ObjectId("5f1408d3c0e8c130503daafd"),
"username" : "Akhil Jagga",
"data" : [
{
"_id" : ObjectId("5f15cde9329fc9300c7f3843"),
"nameOfList" : "home",
"items" : [
{
"_id" : ObjectId("5f15cde9329fc9300c7f3844"),
"nameOfItem" : "this is the list item"
}
]
},
{
"_id" : ObjectId("5f15cebd9a97051d80c6c6ad"),
"nameOfList" : "personal",
"items" : [
{
"_id" : ObjectId("5f15cebd9a97051d80c6c6ae"),
"nameOfItem" : "this is the list item"
},
{
"_id" : ObjectId("5f15cfd0d73dc330dc8e7fd1"),
"nameOfItem" : "lol"
}
]
}
],
"__v" : 48
}
I want to delete a specific object from "items" array say with ObjectId("5f15cebd9a97051d80c6c6ae"), using mongoose in nodejs .
I tried by writting the following code but it does't work:
app.post("/delete", redirectLogin, function(req, res) {
const checkedItemId = req.body.checkbox;
const checkedItemName = req.body.hiddenInput;
const listName = req.body.listName;
console.log("item id: " + checkedItemId);
User.findOneAndUpdate(
{
username: req.session.userId
},
{
$pull: {
data: {
items: {
_id: checkedItemId
}
}
}
},
function(err, foundList) {
console.log(foundList);
res.redirect("/");
});
});
I have tried using findOneAndUpdate, if I write name of item with the
id it deletes the whole list from data array containing that item
name and id.
Thankyou for your time.
Try this one,
const username = req.session.userId;
const listName = req.body.listName;
const checkedItemId = req.body.checkbox;
User.update({ "username": username}, { "$pull": { `data.${listName}.items`: { "_id": checkedItemId } }}, { safe: true, multi:true }, function(err, obj) {
//do rest
});

MongoDB mongoose update elemMatch doesn't work but when query (find) it's ok

I'm having some problems on update using $elemMatch.
When I try to match or find, it shows the write result.
.updateOne(
{ _id: req.body.sid },
{ $pull: {comments: { $elemMatch: { fid: '5ea9c87d2d5c8f491cae8818' } }}}
).then((res)=>{
console.log(res)
}).catch((err)=>{
console.log(err)
})
It's resulting :
{ n: 1, nModified: 0, ok: 1 }
And it's the query result using find:
.find({
$and: [
{ _id: req.body.sid },
{comments: { $elemMatch: { fid: '5ea9c87d2d5c8f491cae8818' } }}
]
})
Sample doc result of find :
[
{
_id: 5ea88b12423e6e4b3ce01956,
comments: [{"fid":"5ea9c87d2d5c8f491cae8818","comment":"ok"}, {"fid":"5ea9c87d2d5c8f491cae8899","comment":"ok"}],
date: 2020-04-28T00:00:00.000Z,
title: 'Fotos para o Álbum de ensaios',
__v: 5
}
]
can anybody help me? Thank you!!
You can try like below :
If your documents look something like :
/* 1 */
{
"_id" : "5ea88b12423e6e4b3ce01956",
"comments" : [
{
"fid" : "5ea9c87d2d5c8f491cae8818"
},
{
"fid" : "5ea9c87d2d5c8f491cae8899"
}
],
"date" : "2020-04-28T00:00:00.000Z",
"title" : "Fotos para o Álbum de ensaios",
"__v" : 5.0
}
/* 2 */
{
"_id" : "5ea88b12423e6e4b3ce01951",
"comments" : [
{
"fid" : "5ea9c87d2d5c8f491cae8811"
},
{
"fid" : "5ea9c87d2d5c8f491cae8899"
}
],
"date" : "2020-04-28T00:00:00.000Z",
"title" : "Fotos para o Álbum de ensaios",
"__v" : 5.0
}
So $elemMatch is not needed on single query condition which in your case {comments: { $elemMatch: { fid: '5ea9c87d2d5c8f491cae8818' } }} can just be "comments.fid": "5ea9c87d2d5c8f491cae8818", also you don't need $and operator in your .find().
Query :
/** Here "comments.fid" helps to filter doc, even though we'll get single doc based on `_id` filter but
* still adding this check prevents unnecessary update operation if `5ea9c87d2d5c8f491cae8818` doesn't exists in fid of comments in doc */
.updateOne(
{ _id: req.body.sid, "comments.fid": "5ea9c87d2d5c8f491cae8818" },
{ $pull: { "comments" :{ "fid": "5ea9c87d2d5c8f491cae8818" } } }
)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});

Mongodb | Romove object from document's array

I tried to remove an object from document array but something not working:
This is my object:
{
"_id" : ObjectId("5b487aa1427e5a1edc1cdbac"),
"location" : {
"latitude" : 0,
"longitude" : 0
},
"email" : "ran#gmail.com",
"firstName" : "Ran",
"lastName" : "Alcobi",
"interests" : [
ObjectId("5b49a44bc3b19929b098547e")
],
}
I removed Interest from the interests collection and I need that the interest will be removed from the Interests array of the user:
this is my code:
router.delete('/:id', (req, res) => {
var id = req.params.id;
if (!ObjectID.isValid(id)) {
return res.status(404).send();
}
Interest.findOneAndRemove({
_id: id,
}).then((interest) => {
if (!interest) {
return res.status(404).send();
}
User.update(
{$pull:
{interests: {$in : interest._id} }
},
{multi: true},
).then((user) => {
console.log(user);
res.send({interest});
}).catch((e) => {
res.status(400).send();
});
});
});
Thanks a lot for helpers. I would be happy to know what is my mistake.
You are passing $pull in wrong parameter of update query... In update query first parameter is for filter and second parameter is for update operation... So you have to first filter with $in and then $pull from the interest array...
So, finally you need to do something like this
User.update(
{ interests: { $in : [interest._id] } },
{ $pull: { interests: interest._id } }
{ multi: true },
)

Mongoose aggregate return empty result and working in mongo console [duplicate]

This question already has answers here:
Moongoose aggregate $match does not match id's
(5 answers)
Closed 6 years ago.
Stack:
+ Mongoose 4.4.10 (last stable version) already tested with older versions
+ MongoDb 2.6.3
I execute that function in mongodb console, with successfully re
db.activities.aggregate(
{ $match : { 'organizer': ObjectId("5408e4609640de8768c1d212") } }
, { $group :
{ _id : "$organizer",
totalSwims: { $sum : 1 },
longestSwim : { $max: "$distance" },
moreDistanceSwim : { $max: "$duration" },
warmestWaterSwim : { $max: "$activityWeather.waterTemperature" },
coldestWaterSwim : { $min: "$activityWeather.waterTemperature" },
warmestSwim : { $max: "$activityWeather.temperature" },
coldestSwim : { $min: "$activityWeather.temperature" }}});
{ "_id" : ObjectId("5408e4609640de8768c1d212"), "totalSwims" : 50, "longestSwim" : 6512.997, "moreDistanceSwim" : "02:35", "warmestWaterSwim" : "22", "coldestWaterSwim" : "22", "warmestSwim" : "15", "coldestSwim" : "15" }
But If I try through mongoose is returning always an empty array [] I already have some aggregate functions working well, but don't know why that one is not working.
activities.aggregate([
{ $match : { 'organizer': userId } },
{ $group : {
_id : "$organizer",
totalSwims: { $sum : 1 },
longestSwim : { $max: "$distance" },
moreDistanceSwim : { $max: "$duration" },
warmestWaterSwim : { $max: "$activityWeather.waterTemperature" },
coldestWaterSwim : { $min: "$activityWeather.waterTemperature" },
warmestSwim : { $max: "$activityWeather.temperature" },
coldestSwim : { $min: "$activityWeather.temperature" }
} } ]
, function(err, result){
if (err) {
console.error('Problem %s', err);
return next(err);
} else {
console.error('Result %j', result);
return next(null, result);
}
});
Any idea?
Thank you
Sorry, after searching for a while before posting without any relevant result I finally figured it out. It seams that, just for that case, I need to ensure the id with the ObjectId method instead to send just an string.
var ObjectID = require("mongodb").ObjectID;
activities.aggregate([
{ $match : { 'organizer': ObjectID(userId) } },

Mongoose: aggregation with $match by "_id.property"

In a mongo (2.4.x) collection with documents with this structure:
db.col.insert({ "_id" : { "owner" : "john" }, "value" : 10 });
db.col.insert({ "_id" : { "owner" : "mary" }, "value" : 20 });
I am using mongoose (3.5.4) and trying to run an aggregation pipeline without success. This works fine from the mongo command line client:
> db.col.aggregate({ $match : { "_id.owner": "john" } });
{ "result" : [ { "_id" : { "owner" : "john" }, "value" : 10 } ], "ok" : 1 }
But it does not work as expected when I use mongoose:
Col.aggregate(
{ $match : { "_id.owner": "john" } },
function(err, result) {
console.log("ERR : " + err + " RES : " + JSON.stringify(result));
}
);
ERR : null RES : []
This is the mongoose Schema I am using:
var Col = new Schema({
_id: {
owner: String
},
value: Number
});
I have to say that a simple Col.find({ "_id.owner": "john" }) works as expected.
How could I make it work? I can not modify the structure of my documents.
As I workaround I included a $project before the match, but I am still looking for a cleaner solution:
{
$project: {
"_id": 0,
"owner": "$_id.owner",
"value": 1
}
}

Resources