How do I update the messageRead attribute in my MongoDb object? - javascript

I have the following object stored in MongoDb. I am sending a messageRead attribute inside my messages array.
I have tried:
collection.updateOne({ '_id': ObjectId(employeeID) },
{
"$set": {
"userObject.messages.message.message_uuid" : { employeeMessageUpdateUUID, "messageRead" : employeeMessageRead }
}
but it does not work. I find the object i'm looking for through the _id, and then try to find the message using the message_uuid however the messageRead attribute is not updating. I am clearly using the wrong Mongo query.. What should my $set look like?

You can use $ operator to do that:
collection.updateOne(
{
'_id': ObjectId(employeeID),
'userObject.messages.message.message_uuid': employeeMessageUpdateUUID
},
{
$set: { 'userObject.messages.$.message.messageRead': employeeMessageRead }
}
)...

Related

Unable to delete element from array of objects using mongoose

I am trying to remove one element from array of objects in MongoDB.
Please find the schema structure below.
I just want to remove one object by status, ideaID and invitedBy. Please find the query I am using for it,
await User.findByIdAndUpdate(
currentUser,
{ $pull: { "invitationStatus.ideaId": this.req.body.ideaId, "invitationStatus.status": "pending", "invitationStatus.invitedBy": getUserByNotificationId.createdBy._id } })
but this query is not removing the specified object.
You have to specify from which field you want to pull item. Change your query like this:
await User.findByIdAndUpdate(currentUser, {
$pull: {
invitationStatus: {
ideaId: this.req.body.ideaId,
status: "pending",
invitedBy: getUserByNotificationId.createdBy._id
}
}
})

Mongoose: Add more items to existing object

Using Mongoose, How can I add more items to an object without replacing existing ones?
User.findOneAndUpdate(
{ userId: 0 },
{ userObjects: { newItem: value } }
);
The problem with above code is that it clears whatever was there before and replaces it with newItem when I wanted it just to add another item to userObjects(Like push function for javascript arrays).
Use dot notation to specify the field to update/add particular fields in an embedded document.
User.findOneAndUpdate(
{ userId: 0 },
{ "userObjects.newerItem": newervalue } }
);
or
User.findOneAndUpdate(
{ userId: 0 },
{ "$set":{"userObjects.newerItem": newervalue } }
);
or Use $mergeObjects aggregation operator to update the existing obj by passing new objects
User.findOneAndUpdate(
{"userId":0},
[{"$set":{
"userObjects":{
"$mergeObjects":[
"$userObjects",
{"newerItem":"newervalue","newestItem":"newestvalue"}
]
}
}}]
)
According to your question, i am guessing userObjects is an array.
You can try $push to insert items into the array.
User.findOneAndUpdate(
{ userId: 0 },
{ $push : {"userObjects": { newItem: value } }},
{safe :true , upsert : true},function(err,model)
{
...
});
For more info, read MongoDB $push reference.
Hope it helps you. If you had provided the schema, i could have helped better.
Just create new collection called UserObjects and do something like this.
UserObject.Insert({ userId: 0, newItem: value }, function(err,newObject){
});
Whenever you want to get these user objects from a user then you can do it using monogoose's query population to populate parent objects with related data in other collections. If not, then your best bet is to just make the userObjects an array.

Unable to push data into current object inside mongo database

I am using mongodb native and Node.js 6.5.0.
I have user object in mongodb which is structured as:
{
"_id" : ObjectId("57d7d294d96a73d128c46db9"),
"id" : "105862592064",
"labels" : [
]
}
I have a loop (for each user found) get data from API and then push it into object attribute of array type. Where user id user.id and data to push is resp.labels.
This is my code:
db.collection('users').update(
{"id":user.id},
{"$push":{"users.labels":resp.labels}}
)
It doesn't return any error, neither it does update objects. What have I done wrong?
Try this:
db.collection('users').update(
{"id":user.id},,
{
$push: {
labels: {
$each: //yourArray
}
}
}
);
$push is for pushing a single element to an array. Use $push together with $each to push multiple elements. Also, quotes around the object labels should not be neccessary:
db.collection('users').update(
{ id:user.id },
{ $push: { labels: { $each: resp.labels } } }
)
Try $set
db.collection('users').update(
{"id":user.id},
{$set:{"users.labels":"hola"}})
Try to include {upsert:true}:
db.collection('users').update(
{"id":user.id},
{"$push":{"users.labels":resp.labels}},
{"upsert": true}
);
Upsert inserts new value if it doesn't already exists.

Mongodb: Add a field into embedded document (no array)

I'm trying to update a mongodb json document by single field. I know it would be easy if my data was in object array but beacause of reasons and uninformed early design choices it's just objects within objects.
structure of the single document in my collection:
{
"_id": 123123,
"drivers_teams": {
"drivers" : {
"4" : { <data> },
"5" : { <data indeed> },
...
},
...
}
}
I want to add new object e.g
const collection = db.get('collection');
let drivers = { };
drivers['111'] = { <new data> };
collection.update({}, {$set: { drivers_teams: { drivers } }}, { upsert: true }, function (err, doc) { ... });
But the outcome is that original objects in "drivers_teams" are wiped out and has only the new field in it.
If I try:
collection.update({}, {$set: { drivers }}, { upsert: true }, function (err, doc) { ... });
It non surprisingly inserts a new field "drivers" outside the drivers_teams
{
"_id": 123123,
"drivers" : { <new data> },
"drivers_teams": { <still original> }
}
Similar problem (+solution) here but json isn't nested like mine.
https://groups.google.com/forum/#!topic/mongodb-user/ZxdsuIU94AY
Is there a way to even accomplish what I'm trying to do? Or should I just give up and overwrite the whole document when I want to update a single field?
EDIT
Working solution here is {$set: { 'drivers_teams.drivers.111': <data> }} but what I should have mentioned is that example key '111' is actually unknown, it comes from client when it sends update data. That's why the new object was created by this solution: dynamically name mongo key field
Writing anything like { 'drivers_teams.driver.' + key: <data> } throws error.
It is given in the documentation of '$set' that to specify a field in an embedded document or in an array, you can use the dot notation. For your case you can do:
collection.update({},
{
$set: { "drivers_teams.drivers.111": { <new data> }}
},
{ upsert: true }, function (err, doc) { ... });
https://docs.mongodb.com/manual/reference/operator/update/set/
Edit:
If you are generating the field name dynamically, you can do:
const collection = db.get('collection');
let set_obj= { };
set_obj['drivers_teams.driver.' + key] = { <new data> };
collection.update({}, {$set: set_obj }})
You missed a level above the drivers sub-document. In mongo shell, I believe what you require is:
db.collection.update({}, {$set: {'drivers_teams.drivers.111': {...}}})
which will update the document to be like:
{
"_id": 123123,
"drivers_teams": {
"drivers": {
"4": {...},
"5": {...},
"111": {...}
}
}
}
Please see the Embedded Documents page for more details regarding the dot notation used by MongoDB.

Mongodb save into nested object?

I can't get my req.body inserted into my mongodb collection.
I have this route that triggers the add method and inside I am trying to figure out a query to save the req.body into a nested collection array
router.post('/api/teams/:tid/players', player.add);
add: function(req, res) {
var newPlayer = new models.Team({ _id: req.params.tid }, req.body);
newPlayer.save(function(err, player) {
if (err) {
res.json({error: 'Error adding player.'});
} else {
console.log(req.body)
res.json(req.body);
}
});
}
Here is an example document
[
{
"team_name":"Bulls",
"_id":"5367bf0135635eb82d4ccf49",
"__v":0,
"players":[
{
"player_name":"Taj Gibson",
"_id":"5367bf0135635eb82d4ccf4b"
},
{
"player_name":"Kirk Hinrich",
"_id":"5367bf0135635eb82d4ccf4a"
}
]
}
]
I can't figure out how to insert/save the POST req.body which is something like
{
"player_name":"Derrick"
}
So that that the new req.body is now added into the players object array.
My question is how do I set the mongodb/mongoose query to handle this?
P.S I am obviously getting the error message because I don't think the query is valid, but it's just kind of an idea what I am trying to do.
Something like this is more suitable, still doesn't work but its a better example I guess
var newPlayer = new models.Team({ _id: req.params.tid }, { players: req.body });
If you created a Team model in Mongoose then you could call the in-built method findOneAndUpdate:
Team.findOneAndUpdate({ _id: req.params.tid },
{ $addToSet: { players: req.body} },
function(err, doc){
console.log(doc);
});
You could do findOne, update, and then save, but the above is more straightforward. $addToSet will only add if the particular update in question doesn't already exist in the array. You can also use $push.
The above does depend to an extent on how you have configured your model and if indeed you are using Mongoose (but obviously you asked how it could be done in Mongoose so I've provided that as a possible solution).
The document for $addToSet is at http://docs.mongodb.org/manual/reference/operator/update/addToSet/ with the relevant operation as follows:
db.collection.update( <query>, { $addToSet: { <field>: <value> } } );

Categories

Resources