MongoDB update document object - mongodb

user = users.findOne({
"$or": [{
'local.email': 'some#email.com'
}, {
'google.email': 'some#email.com'
}, {
'facebook.email': 'some#email.com'
}]
// do stuff with user object
So I have the user object. This is fine, after I'm finished with what I need from it property wise I wish to update some of the fields in this object now, I've tried the following without it working:
user.local.email = 'other#email.com';
users.update(user);
Is this not a viable way of updating a document?

Use the $set operator to update your document as follows:
db.users.update(
{
"$or": [
{'local.email': 'some#email.com'},
{'google.email': 'some#email.com'},
{'facebook.email': 'some#email.com'}
]
},
{
$set: {
'local.email': 'other#email.com'
}
}
)
With the update method, you do not need to do another query which finds the document you want to update because the update() method takes in a query parameter which is the selection criteria for the update, the same query selectors as in the find() method are available. Read more on the update method in the Mongo docs here.

This was the better suited solution.
user.local.email = 'other#email.com';
users.update({
"$or": [{
'local.email': 'some#email.com'
}, {
'google.email': 'some#email.com'
}, {
'facebook.email': 'some#email.com'
}]
}, user);

Related

how to update the name of multiple objects to lowercase in mongodb?

i need to update the all user who have the rol user and change the nickName to lowercase, i try with this code
const users = await userModel.updateMany({ rol:'user' },
{
$set:{
nickName: {
$toLower : "$nickName"
}
}
});
but is not working
In the future, please describe in what way your approach is not working. I went ahead and copied your example into this playground example and saw that your current approach resulted in the document being modified to include this field:
"nickName": {
"$toLower": "$nickName"
}
The problem here is that you are attempting to use the (aggregation) $set stage in your update (so that you can reference the existing $nickName field), but the update is using the $set (non-aggregation) modifier. If you wrap your second argument in square brackets (telling the database that you want to use an aggregation) then it should do what you want:
db.collection.update({
rol: "user"
},
[
{
$set: {
nickName: {
$toLower: "$nickName"
}
}
}
])
Playground demonstration here

Can't remove object in array using Mongoose

This has been extensively covered here, but none of the solutions seems to be working for me. I'm attempting to remove an object from an array using that object's id. Currently, my Schema is:
const scheduleSchema = new Schema({
//unrelated
_id: ObjectId
shifts: [
{
_id: Types.ObjectId,
name: String,
shift_start: Date,
shift_end: Date,
},
],
});
I've tried almost every variation of something like this:
.findOneAndUpdate(
{ _id: req.params.id },
{
$pull: {
shifts: { _id: new Types.ObjectId(req.params.id) },
},
}
);
Database:
Database Format
Within these variations, the usual response I've gotten has been either an empty array or null.
I was able slightly find a way around this and accomplish the deletion by utilizing the main _id of the Schema (instead of the nested one:
.findOneAndUpdate(
{ _id: <main _id> },
{ $pull: { shifts: { _id: new Types.ObjectId(<nested _id>) } } },
{ new: true }
);
But I was hoping to figure out a way to do this by just using the nested _id. Any suggestions?
The problem you are having currently is you are using the same _id.
Using mongo, update method allows three objects: query, update and options.
query object is the object into collection which will be updated.
update is the action to do into the object (add, change value...).
options different options to add.
Then, assuming you have this collection:
[
{
"_id": 1,
"shifts": [
{
"_id": 2
},
{
"_id": 3
}
]
}
]
If you try to look for a document which _id is 2, obviously response will be empty (example).
Then, if none document has been found, none document will be updated.
What happens if we look for a document using shifts._id:2?
This tells mongo "search a document where shifts field has an object with _id equals to 2". This query works ok (example) but be careful, this returns the WHOLE document, not only the array which match the _id.
This not return:
[
{
"_id": 1,
"shifts": [
{
"_id": 2
}
]
}
]
Using this query mongo returns the ENTIRE document where exists a field called shifts that contains an object with an _id with value 2. This also include the whole array.
So, with tat, you know why find object works. Now adding this to an update query you can create the query:
This one to remove all shifts._id which are equal to 2.
db.collection.update({
"shifts._id": 2
},
{
$pull: {
shifts: {
_id: 2
}
}
})
Example
Or this one to remove shifts._id if parent _id is equal to 1
db.collection.update({
"_id": 1
},
{
$pull: {
shifts: {
_id: 2
}
}
})
Example

Delete an array element inside a document with mongoose

I'm not sure if Ihave to get the document ,change the object an d update it on the database or if I can update the document on one step
on this document:
{
"_id":{"$oid":"5fb15c68daa5c11cf5d6d4b3"},"state":[],
"users":[
{"_id":{"$oid":"5fb15c68daa5c11cf5d6d4b4"},"user":{"$oid":"5f81eb91d537dc3baf443a84"},"calification":0},
{"_id":{"$oid":"5fb15c9cdaa5c11cf5d6d4b5"},"user":{"$oid":"5fa6f98f15e96c1125b905a9"},"calification":0}
],
"test":{"$oid":"5f986af2baa88b2d30760961"},
"__v":1}
I know the document id and the users array element id, its possible to delete it in one query?
UPDATE:
I'm using , this code but nothing its done
Game.update({
"_id": req.body.game_id,
},
{
"$pull": {
"users": {
"user": '5f81eb91d537dc3baf443a84'
}
}
})
Yes, you can do in one query.
If I've not missunderstood the question, you only need this:
db.collection.update({
"_id": document_id,
},
{
"$pull": {
"users": {
"_id": user_id_to_remove
}
}
})
You look for the document and then $pull the element which has _id 1 (or whatever you want).
Example here
Note that you can use user field if you want instead of _id.

Nested Mongodb Query needing multi seareshes

Hi I'm new with mongodb and I have to write a query to check if each field in database has a parent, if yes change the hasChild field to "true" else leave it be the default value of false.
Here is sample of one Document.
{
"_id":"5e19ef611052250ba51abb7b",
"name":"shampoo",
"price":12.99,
"hasChild":true
}
{
"_id":"5e1b268d25fe046b3518dcb9",
"name":"conditioner",
"price":"13.99",
"parent":"5e19ef611052250ba51abb7b",
"hasChild":false
}
I though a query which could ,while updating a filed search in other documents, check whether they have a parent id same as current documents id and set true/false would work out. but I couldn't find a way to write it. I would appreciate any ideas.
note that "_id" and "parent" are ObjectId.
You can do it with aggregation framework.
Something like this with $addFields and $cond:
db.getCollection("yourcollection").aggregate(
[
{
$addFields: {
"hasChild": {
$cond: { if: { $eq: [ "$parent", undefined ] }, then: false, else: true }
}
}
},
]
);

How to add ObjectId property to each object of an array

I am have manually created an object in a Mongo collection:
{
"messages": [
{
"url":"http://test.test.com",
"message":"test message"
}
],
....other properties
}
I would like to add an _id:ObjectId() to each item of my messages array and for each document in the collection.
I tried:
collection.update({}, {
$set: {
'messages.$._id': ObjectId(),
},
}, { multi: true }
but this is not working. The Id is getting added when I add new ones going through Mongoose, but these were manually entered into mongo. Any help is appreciated.
Your syntax is correct, but in order to use the $ positional operator the array field must appear as part of the query document, check in documentation.
Try this:
db.collection.update({messages: {$exists: true }},
{$set: { 'messages.$._id': ObjectId() } },
{multi: true}
)