find and update one field in array of subdoc mongoose - node.js

i'm new in mongodb and mongoose. i'm using node js, and i want to find and update specific field in one of array in sub document.
here is my data structure :
var PostSchema = new Schema({
title: String,
comment: [
{
name: String,
value: String
}
],
createdAt: Date,
updateAt: Date
})
this is my data example :
{
_id : 12,
title : 'some article here...',
comment : [{
_id : 1,
name : 'joe',
value : 'wow that fantastic...'
},{
_id : 2,
name : 'rocky',
value : 'really... thats insane...'
},{
_id : 3,
name : 'jane',
value : 'i think its impossible to do...'
}],
createdAt : 2016-04-14 04:50:54.760Z,
updatedAt : 2016-04-14 04:50:54.760Z
}
i need to update comment which have _id : 2, i want to change the value become 'what???'. i try to update with :
Post.findOne({'_id': 12, 'comment._id': 2}, {_id: 0, 'comment.$': 1}, function (err, cb) {
cb.comment.value = 'what???'
cb.save()
})
but it failed... so, can you help me? Thanks

you can use findOneAndUpdate and positional operator $ to update specific comment value
Post.findOneAndUpdate({"_id": 12, "comment._id": 2},
{
$set: {
"comment.$.value ": "New value set here"
}
},
{ new: true } // return updated post
).exec(function(error, post) {
if(error) {
return res.status(400).send({msg: 'Update failed!'});
}
return res.status(200).send(post);
});

It will work for array updation in mongodb using mongoose
Post.findOneAndUpdate(
{ id: 12,comment_id:2 },
{ $push: { comment:"new comment" } }
)

Related

MongoError: Cannot apply $addToSet to non-array field. Field named 'trackTime' has non-array type string

Here i'm trying to update with the userid, trackTime fields. Evertime userid and trackTime will be different so i'm using $addToSetbut here i'm facing an error
like this i'm passing the data in postman:-
{
"courseId":"61001184afeacb22ac1668e0",
"userId":"60f6fe96a1a44a1fb4a59573",
"trackingTime":"4"
}
this is the schema:-
usersEnrolled : [{
iscourseenrolled : { type:Boolean, default: false },
userId: {type: String },
trackTime: {type:String}
}],
code:-
const updatedTrackTime = await Courses.updateOne({ "_id" : req.body.courseId},{
$addToSet:{
"usersEnrolled.0.userId" : req.body.userId,
"usersEnrolled.0.trackTime": req.body.trackingTime
}})
The reason for that error is probably because you didn't specify the array field (Actually you didn't specify any field at all). Try to add your usersEnrolled field like this:
const updatedTrackTime = await Courses.updateOne({ "_id" : req.body.courseId},{
$addToSet:{
usersEnrolled: {
"usersEnrolled.0.userId" : req.body.userId,
"usersEnrolled.0.trackTime": req.body.trackingTime
}
}});
To get more details on $addToSet use MongoDB Manual
https://docs.mongodb.com/manual/reference/operator/update/addToSet/
I just changed in to these and it worked for me
const updatedTrackTime = await Courses.updateOne({ "_id" : req.body.courseId},{ $addToSet:{
usersEnrolled : {
userId : req.body.userId,
trackTime: req.body.trackingTime
}

How can I update 2 or more unique documents in mongoose db

I have 3 unique documents in mydb, I want to update each document using there unique keys that are generated randomly.
I tried updateMany() and update({multi:true}). Using upadteMany() we can update the document that matches the query. Is there any way that I can solve this problem?
Thanks in advance.
If I have the following documents:
doc1 : {
_id: 1,
name: 'John Smith',
age: 20
}
doc2 : {
_id: 2,
name: 'Jane Smith',
age: 22
}
I want the client to be able to pass me both docs in the same request for update. In this case maybe add an address to both docs.
Is there a way the I can send one update statement to mongo such that it updates both of the documents with the name values?
the answer you provided is good. but i modified that code and it looks like
_id: { $in: [req.params.noteId,req.params.noteId,req.params.noteId]}
}
Note.updateMany(query,
{$set:{
lname: req.body.lname || "Untitled Note",
age: req.body.age
}}
, { new: true }
)
this code is not working
From the below code you can solve your problem .
//consider the following object to update
doc1 : {
_id: 1,
name: 'John Smith',
age: 20
}
doc2 : {
_id: 2,
name: 'Jane Smith',
age: 22
}
The below code will change the name of both the docs to manjesha
var criteria = {
_id : { $in : [ "1" , "2"] }
}
userModel.update(criteria , { name: "manjesha" }, { multi: true },function(err , found){
if(err){
res.send(err);
}else{
res.send(found);
}
});
// $in -The $in operator selects the documents where the value of a field equals any value in the specified array.
This will work perfect on your problem .

Can't get figure it out: mongoose update a doc inside an array inside a doc

Well I want to update a doc inside an array by the index. My schema and code look like this
var userSchema = mongoose.Schema({
email: {
type: String,
required: false,
minlength: 4,
trim: true
},
bla: []
});
// this is the example object that I get from the db
{
"id" = "somethingUniq",
"email" = "this#email.workdamnit",
"bla" = [{"blabla": "something"},{"blabla":"somethingelse"}]
}
User.findOneAndUpdate({ "_id": "somethingUniq", "bla.1.blabla": "something" },
{
"$set": { "bla.$.blabla": "something new" },
function(err, doc) {
if (err) console.log('err in update', err);
console.log('doc', doc)
}
})
So that blabla with index of 1 gets updated. I have tried for hours now, and can't get anything I try to work...
The end result should look like :
{
"_id" = "somethingUniq",
"email" = "this#email.workdamnit",
"bla" = [{"blabla": "something"},{"blabla":"something new"}]
}
The $push operator appends a specified value to an array.
( https://docs.mongodb.com/manual/reference/operator/update/push/ )
Try $set in your case :
User.findOneAndUpdate(
{ "_id": "somethingUniq",
"bla.1.blabla": "something"
},
{ $set:{
"bla.$.blabla": "something new"
}
},
function(err,result){
if (!err) {
console.log(result);
}
});
And make sure you're using the correct one between _id and id because you're showing both of them in your subject.
In the case you're looking for id, change also :
"_id": "somethingUniq"
To :
"id": "somethingUniq"

How to find a record using dot notation & update the value in a schema using mongoose

I am using mongoose to perform CRUD operation on my db. This is how my model looks.
var EmployeeSchema = new Schema({
name: String,
description: {
type: String,
default: 'No description'
},
department: [],
lastUpdated: {
type: Date,
default: Date.now
}
});
The department can contains array of object like this.
[
{
"id" : "55ba28f680dec4383eeebf97",
"text" : "Sales",
"topParentId" : "55ba28f680dec4383eeebf8b",
"topParentText" : "XYZ"
},
{
"id" : "55ba28f680dec4383eeebf98",
"text" : "IT",
"topParentId" : "55ba28f680dec4383eeebf8b",
"topParentText" : "XYZ"
},
{
"id" : "55ba28f680dec4383eeebf94",
"text" : "Marketing",
"topParentId" : "55ba28f680dec4383eeebccc",
"topParentText" : "ABC"
}
]
Now I need to find all the employee where department.id = '55ba28f680dec4383eeebf94' and then I need to update the text of the object.
Employee.find({'department.id': '55ba28f680dec4383eeebf94'}, function(err, Employees) {
_.each(Employees, function (emp) {
_.each(emp.department, function (dept) {
if(dept.id === '55ba28f680dec4383eeebf94'){
dept.text = 'XXXXX'; // How to update the employee to save the updated text
}
});
});
});
What is the right way to save the employee with updated text for that department?
Iterating is code is not a "sharp" way to do this. It is better to use the MongoDB update operators, especially since there is no schema defined for the array items here, so no rules to worry about:
Employee.update(
{'department.id': '55ba28f680dec4383eeebf94'},
{ "$set": { "department.$.text": "XXXXX" },
function(err,numAffected) {
// handling in here
}
);
The $set is the important part, otherwise you overwrite the whole object. As is the positional $ operator in the statement, so only the matched ( queried item in the array ) index is updated.
Also see .find**AndUpdate() variants for a way to return the modified object.
I think you can use the update model:
Employee.update({department.id: '55ba28f680dec4383eeebf94'}, {department.text: 'XXXXX'}, {multi: true},
function(err, num) {
console.log("updated "+num);
}
);
First object is the query, what to find: {department.id: '55ba28f680dec4383eeebf94'}, the second one is the update, what to update: {department.text: 'XXXXX'} and the third one is the options to pass to the update, multi means update every records you find: {multi: true}

Mongoose MongoDB: updating objects in a nested array

I've got the following schema
var UserSchema = new Schema({
emp_no: Number,
skills: [{
skill: {
type: Schema.Types.ObjectId,
ref: 'Skill'
},
startDate: {type: Date},
}]
});
I'm then trying to update the startDate of one particular skill. I've tried several differents ways, one of them being:
User.findOne({emp_no: req.body.emp_no}, function (err, user) {
user.update( {'skills._id': 123}, {'$set': {
'skills.$.startDate': req.body.startDate
}}
}
This particular code gives: err: 'cannot use the part (skills of skills._id) to traverse the element
The actual object looks like
{
"_id" : ObjectId("5469753de27a7c082203fd0a"),
"emp_no" : 123,
"skills" : [
{
"skill" : ObjectId("547d5f3021d99d302079446d"),
"startDate" : ISODate("2014-12-02T06:43:27.763Z")
"_id" : ObjectId("547d5f8f21d99d3020794472")
}
],
"__v" : 108
}
Any ideas what I'm doing wrong?
When you call update on a model instance like you're doing here, the first parameter is the update operation to apply to that document, as the document to update is already uniquely identified by its _id.
Instead, use Model.update to do this all in one operation:
User.update(
{emp_no: req.body.emp_no, 'skills._id': 123},
{'$set': {
'skills.$.startDate': req.body.startDate
}},
function(err, numAffected) {...}
);

Resources