I am trying to update a document in mongo with mongoose using updateOne method:
const updateResult = await UserModel.updateOne({
_id: mongoose.Types.ObjectId(userId)
}, {
$set: {
a: 'B'
}
})
userId contains a string of the ID of the user.
I have tried using the following
1. { _id: userId }
2. { email: theEmailOfTheUser }
But still, the updateResult is
n:0, nModified:0, ok:0
So I think it's must be something with the method itself and not in my query.
Also, when I'm trying to find the user using the query below, it can find it:
const user = await UserModel.find({
_id: userId
});
//user is found
Actually mongoose takes care of the $set and you do not have to add it. just:
const updateResult = await UserModel.updateOne({
_id: userId
}, {
a: 'B'
})
but the better solution would to just use findByIdAndUpdate():
const updateResult = await UserModel.findByIdAndUpdate(userId, {
a: 'B'
})
Related
Is the first time I am working with backend (Mongoose, express, nodeJs). I have a collection of users in MongoDB.
I am sending the favoriteId from frontend and getting it in the backend. I want to delete the position of the array that matches with the favorite Id I am passing to the function.
I have tried several ways to remove the favorite using the $pull operator and the favoriteId but none work. So I don't know how to do it.
I would appreciate if someone could help me.
This is structure in MongoDB:
_id: new ObjectId("63"),
username: 'test1',
email: 'test1#gmail.com',
favorites: [
{
id: '25',
version: 'version3',
team: 'team1',
},
{
id: '27',
version: 'version2',
team: 'team4',
}```
This is my controller function:
```export const removeFavorite = async (req, res) => {
//Here I have the user Id 63
const userId = req.params.userId;
//here I have the favorite Id I Want to remove : 25
const favoriteId = req.body.params.id;
// Here I select the user in the collection
const deleteFavorite = await User.findOne({ _id: userId });
// Here I want to remove the favorite that matches with favoriteId (25)
res.status(200).json('ok');
};```
Try this:
User.update({ _id: userId }, { $pull: { 'favorites': { 'id': favoriteId } } });
I am trying to build a social network. I have a collection of "connections"/"friend requests".
the schema is as follows:
{
senderId: { type: String },
receiverId: { type: String },
approved: { type: Boolean },
},
when the person didn't approve the connection yet, the connection is marked with "pending".
when the user enter to the website, i get all the pending connections people sent him, with this command:
const requestsPending = await Connection.find({
receiverId: userId,
approved: false,
});
the thing is, in the backend, I want to get the details of the people who send the friend requests (so I can show their name+picture).
I want to loop over the pending requests array, and get the extra data of the user who sent the request.
await User.findById(requestsPending[0][senderId]);
any idea how to do it for each element? what's the best approach?
or any idea how to do it more efficiently?
thank you.
this seems to work:
var requestsPendingWithUsersData = await Promise.all(
requestsPending.map(async (item) => {
const userData = await User.findById(item.senderId);
return {
item,
senderData: { picture: userData.picture, name: userData.username },
};
})
);
await User.find({
'senderId': { $in: [
101,102,103,...
]}
})
You can try something like the above, where you pass an array of senderID to $in. The $in clause is similar to like operator in SQL.
If the senderId is an ObjectId, pass them as ObjectID types
await User.find({
'senderId': { $in: [
mongoose.Types.ObjectId(<senderID>),
]}
})
If the mongo Document is heavier/larger, use lean() at the end of the query. Enabling the lean option tells Mongoose to skip instantiating a full Mongoose document.
await User.find({
'senderId': { $in: [
101,102,103,...
]}
}).lean()
is that posible to reuse already exec mongodb/mongoose query in nodejs?
for example i create query like this to check if user exist or not:
const inviter = await User.findOne({ _id: req.userData._id }).exec()
// there's bunch of code bellow here before update the user data
basically if i want to update the data, then i have to write the same code again and add update function like this:
User.findOneAndUpdate({ _id: req.userData._id }, { $push: { invited: recipient.value } }, { useFindAndModify: false })
is that posible to continue the first query and add short query to update based on result of the first query, for example like this:
inviter.update({ $push: { invited: recipient.value }).exec()
i know this code is not work..
you can use this approach :
User.findOne({ _id: req.userData._id }).exec((err, result) => {
if(result)
{
result.invited = recipient.value;
result.save((err) => {
if (err) // do something
});
}
})
}
I am wondering what would be the best approach to make schema functions using mongoose. I have never used this so the way I think is somewhat limited, same goes for looking for docs, without knowing what's available, is not very efficient.
Through docs I found that either using findOneAndUpdate might solve the problem; but there are some constraints.
Here is the code I am planning to run:
models/Bookmark.js
const mongoose = require('mongoose')
const bookmarkItemSchema = new mongoose.Schema({
restaurantId: String,
cachedAttr: {
name: String,
latitude: Number,
longitude: Number,
},
})
const bookmarkListSchema = new mongoose.Schema({
listName: String,
items: [bookmarkItemSchema],
})
const bookmarkSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
lists: [bookmarkListSchema],
})
// const add = (lists, userId) => {
// let bookmark = Bookmark.findOne({userId})
// bookmark.lists.listName === lists.listName //current, new
// ? bookmark.lists.items.push(lists.items)
// : bookmark.lists.push(lists)
// return bookmark
// }
mongoose.model('Bookmark', bookmarkSchema)
Routes/bookmark.js
router.post('/bookmarks', async (req, res) => {
const {lists} = req.body
console.log(lists)
if (!lists) {
return res.status(422).send({error: 'You must provide lists'})
}
let bookmark = Bookmark.findOne({"userId": req.user._id})
if (bookmark.lists.listName === lists.listName){
let item = lists.items
bookmark.lists.items.push(item)
await bookmark.save()
res.send(bookmark)
}
try {
// const bookmark = Bookmark.add(lists, req.user._id, obj)
// await bookmark.save()
// res.send(bookmark)
let bookmark = Bookmark.findOne({"userId": req.user._id})
if (bookmark.lists.listName === lists.listName){ // THIS IS UNDEFINED. How to get this object?
let item = lists.items
bookmark.lists.items.push(item)
await bookmark.save()
res.send(bookmark)
}
} catch (e) {
res.status(422).send({error: e.message})
}
})
The req.body looks like this:
{
"lists": {
"listName": "My Saved List",
"items": {
"restaurantId": "abcdefg",
"cachedAttr": {
"name": "abcdefg",
"latitude": 200,
"longitude": 200
}
}
}
}
Basically what I commented out in the models/Bookmark.js file is what I would really like to do.
If the userId's list name already exists, then I would like to just add an item to the list.
Otherwise, I would like to add a new list to the object.
What is the best approach for doing this? Is there a straight forward mongoose api that I could use for this problem? or do I need to make two separated function that would handle each case and make that as schema methods and handle it in the routes file?
I am running a utility to update all documents. I don't know what am I doing wrong in the code. Here is my code.
let userId = userIds.pop();
let allMembers = await Member.find({ userId: userId }).lean();
allMembers = allMembers.map((obj) => obj._id);
await Member.updateMany({ _id: { $in: allMembers } }, { $inc: { index: 1 } });
the index does not exist in my document.
Looking for a solution!