MongoDB $pull Query Doesn't Work Properly - node.js

Guys I want to make a unfollow request with $pull qıery but it doesnt work. How to solve this?
Also this method works fine with $push query when I want to follow request user but it doesnt work with $pull.
My app.js:
app.post('/unfollow/:id', function(req, res){
User.find(req.user
).exec(function(err, user){
if(err){
console.log(err);
}
User.find({"username":req.params.id}, function(err, friend){
if(err){
console.log(err);
}
User.update(user,{$pull: { follow: friend}}, function(err){
if(err){
console.log(err);
}else{
res.send("Success")
}
});
});
});
});
This is my how user's follow look like:
{ follow:
[ 5edfe8f3bfc9d677005d55ca,
5edfe92fbfc9d677005d55cc,
5ee2326cc7351c5bb0b75f1a ],
I will take friend id from this array.
And my user model(Follow part):
follow:[{
type: ObjectId,
}]
If pull doesnt work can you suggest me queries or ways to do unfollow request.

User.find({ username: req.params.id } would return a document but looks like you do store ObjectIds in follow field. I except changing $pull: { follow: friend } to $pull: { follow: friend._id } should solve the problem.

Related

mongoose: findOne using mongo _id

I get that this can be a duplicated question. I looked up at least 10 related questions and answers, but I am still not able to find the document.
I am trying to get the document using .findOne(). I have the _id that created by MongoDB. But, I get null for every search I try.
await mongoose.connection.db
.collection('testing')
.findOne({ _id: req.body.test_id }, (err, result) => {
if (err) {
res.status(400);
} else {
console.log(`whaaaaaahsidufh ${result}`);
}
});
I tried _id: mongoose.Type.ObjectId(req.body.test_id) and other possible way to search. How can I retrieve the result by using _id on mongoose?
you can use findById();
try {
const test = await mongoose.connection.db.collection('testing').findById(req.body.test_id);
if (test ) {
console.log(`whaaaaaahsidufh ${test}`);
} else {
console.log(`test not found`);
}
}catch(err){
res.status(400);
}

How to perform deep populate mongoose?

this is my question.js and user.js schema model with mongoose as below, could anyone help how to populate all the username lists in array object of likes:[] with Node js because I was facing this problem almost 2 weeks now, I could not populate the username from a user inside likes. Please, I appreciate your suggestion.
question schema model
user schema model
To populate user details, Please use
Post.findOne( { _id: id } )
.populate( "user" )
.populate( "likes.user" );
To get liked post, please use
Post.find({ "likes": { "$gt": 0 } }, function(err, data) {
})
or using where, here may get error if likes fields is missing or empty, so please check if it is exists
Post.find( {$where:'this.likes.length>0'} )
so please use where and exists
Post.find( {likes: {$exists:true}, $where:'this.likes.length>0'} )
I tried your code and got it working using your model. If you are using user only you can directly call .populate("user") but if its nested you need to do .populate("likes.user")
Post.findOne( { _id: id } ).populate( "user" ).populate( "likes.user" );
Yes, thank you to Ratnadeep Bhattacharyya, now I able to populate username in likes array object and also able to return the only a specific array of likes. Below is the working code:
Happy Coding, Jonh
//#route api/post/get/likes
router.get('/get/likes/:postId', auth, async (req, res) => {
try {
//check if post exist
const likes = await Post.findOne({ _id: req.params.postId })
.populate('user', ['name'])
.populate('likes.user', ['name']);
return res.status(200).json(likes.likes);
} catch (error) {
console.log(error.message);
res.status(500).json({ msg: 'Server error' });
}
});

Update many records by id

i'm woking with mongoose on a project and i have the following issue:
I need to update many records by its ids ( these ids was stored in an array ), i've tried this method:
Collection.update({$in:{"_id":ids}}, {$set:{data_of_id}}, {upsert : true},
{"multi": true}, function(err, res){
if(err){ console.log(err) };
console.log(res);
});
ids[] is the ids of the collection i need to update, and data_of_id is the new records wich will replace the old records. But i don't know how to associate these ids with each record in the array. I tried to put the update query into a foreach method too, but no success. The query above don't return any error or message, the called method was executed but don't execute the query.
The $in syntax is incorrect, it should be:
{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }
So, you should write it like this:
Collection.update({_id: {$in: ids}}, ...);
I've solved doing by this way:
datas.forEach(function(data){
Collection.update({"_id":data._id},
data, {upsert : true},{new : true}, function(err, res){
if(err) console.log(err);
});
});

Remove element from array that is inside of another array in mongoose

The problem is that i can't remove an attachment from an object, in mongoose, with the next schema.
var question=mongoose.Schema({
_id:mongoose.Schema.Types.ObjectId
answers:[{
_id:mongoose.Schema.Types.ObjectId
attachments:[
_id:mongoose.Schema.Types.ObjectId
]
}]
});
I try to remove an attachment from a document with the next code.
Question.update({
_id: req.params.idQuestion,
'answers._id': req.params.idAnswer
}, {
$pull: {
'answers.$.attachments':{_id:req.params.idAttachment}
}
}, function (err, updated) {
if(err){
return res.status(400).send(err);
}
else if(!updated.nModified){
return res.status(400).send('Question hasn\t been updated.');
}
res.send(200);
});
I thought my query weren't correct and tried to do that in mongo shell. It worked perfectly.
db.questions.update({
_id:ObjectId('xx'),
'answers._id':ObjectId('yy')
},{
$pull:{
'answers.$.attachments':{_id:ObjectId('zz')}
}
})
Someone can help me with this problem?
Try this:
var qid=req.params.idQuestion,
aid=req.params.idAnswer;
//find
Question.find({
_id: qid,
'answers._id': aid
},{
answers:1
},function(err,question){
//change
var answers=question.answers.filter(function(el){
return el._id!=aid;
});
//update
Question.update({
_id: qid,
},{$set:{
answers:answers
}},function(err,updated){
...//your callback here
});
});

Updating mongodb and rendering it

I am learning mongodb, node.js and mongoose and want to update a mongodb and then display it on my browser. However my code only displays the results prior to my update even though I know the database has already been updated.
So for example I have two students called John and Tom, but when I update it with a third student called Fred and try to render the results, it only gives me John and Tom's details. Here is my code:
create: function(req, res) {
console.log('creating model');
var newStud = new Models.Student({
surname: req.body.surname,
firstname: req.body.firstname,
}
);
console.log('saving model');
newStud.save();
console.log('rendering model');
Models.Student.find({},
function(err,result){
console.log('finding results');
if (err) {
throw err;}
else {
console.log('returning results');
res.send(result);
}
}
);
},
When I update it with Fred's details, the console outputs the following:
creating model
saving model
rendering model
finding results
returning results
POST /students 200 21.629 ms - 5195
but the page only shows the following:
[
{
"surname": "Smith",
"firstname":"John"
"_id": "55bed36461521187445e5b53",
"__v": 0
},
{
"surname": "Peters",
"firstname":"Tom",
"_id": "55bed3f6c4faaa63464fc6df",
"__v": 0
},
]
I suspect my callback is not working properly. Can anyone explain why? Any help is most appreciated.
The problem here is of course that .save() is an asynchronous method in itself. So to need to wait for it to respond before asking for data from the collection. Otherwise, it likely has not actually created the new item yet:
create: function(req, res) {
console.log('creating model');
var newStud = new Models.Student({
surname: req.body.surname,
firstname: req.body.firstname,
}
);
console.log('saving model');
newStud.save(function(err,doc) { // <-- callback here
console.log('rendering model');
Models.Student.find({},
function(err,result){
if (err) {
throw err;}
else {
console.log('returning results');
res.send(result);
}
}
);
});
});
So basically you need to "wait" for the other .save() action to respond before you go query the whole collection to see the new addition.

Resources