Mongodb update command ask - node.js

What is the command that can update data shown in image1 to become data shown in image2,
I use update $push, but doesn't work.
Error for the command is:
Cannot apply $push modifier to non-array for field 'single'
Starts as:
I want it to be:

Documents should be selected by some field. _id field is the most common for selection. I've used _id from your screenshot.
const _id = 'z6cQHB4WauGgCBGxM';
db.collection.update({
_id: _id
}, {
$push: {
'single.hub': {
context: 222
}
}
});

Related

Update a value inside array of objects, inside a document in MongoDB

Here is what my collection looks like
Now suppose I have to update count of 2nd document whose reportTypes.reasonId is 300. I have access to _id as well as reasonId to update the count. I am using Mongoose to query things in my Node application.
What can I try to solve this?
You can do it via arrayFilters:
db.collection.update(
{
managerId:3
},
{
$inc:{"reportTypes.$[x].count":1}
},
{
arrayFilters:[{"x.reasonId":300 }]
}
)
playground
Explained:
Specify the matching document in the query part and create arrayFilter "x" matching the correct reportTYpes array subdocument , in the update part use the $inc operation to increment the count value in the example with 1
you should use dot notation and the $ update operator to do this:
(I'm assuming your collection is called Reason)
var conditions = {
'_id': '6244........',
'reasonTypes.reasonId': 300
}
var update = {
$inc: {
'reasonTypes.$.count': 1
}
};
Reason.update(conditions, update, function(err) {
// Handle error here
})
You can find more on the operator here mongo $ update operator

MongoDB update query in subarray

An update in the array of objects inside another array of objects.
mongodb field that I'm working on:
otherFields: values,
tasks: [
{
_id: mongodb.objectID(),
title: string,
items:[{
_id: mongodb.objectID(),
title: string,
completed: boolean //field need to be update.
}]
},
{}...
],
otherFields: value
sample mongodb document
I need to find the document using the task_id and the item_id and update a completed field in item of a task. Using the mongoose findOneAndUpdate method
const path = "tasks.$.items." + item_id + "completed";
collectionName.findOneAndUpdate(
{ _id: req.user._id, "tasks._id": taskID },
{ $set: { [path]: true }});
The above query doesn't work!!!
There is no need to use multiple query conditions, since you'd like to update a specific item that has an unique ID. Therefore you could use something along the lines:
collectionName.findOneAndUpdate(
{ 'tasks.items._id': itemID },
...
);
Keep in mind this structure is far away from optimized as it would basically look through the entire database...
Also now that I think of it, you'd also have issue with the update, as there are two nested arrays within the document. Read more here: How to Update Multiple Array Elements in mongodb

how to refer to the field of found document in mongoose?

I am using Mongoose in Node.js and I have a problem
I want to update a field in the document , for example, add a suffix for a filed
how do I refer to the field of found document in update action?
I try to use this. to reference the found document's fields, but it doesn't work?
what should I do?
tcModel.findOneAndUpdate({}, {title: this.title + 'x'}).then((data) => {console.log(data)})
You can use $concat in Updates with Aggregation Pipeline to do that:
tcModel.findOneAndUpdate({}, [{ $set: { title: { $concat: ["$title", "x"] } } }])...

DivergentArrayError in mongoose while updating array of referenced docs

I have a schema defined in mongoose as follow:
var VolunteerSchema = new Schema ({
......
other fields
.....
preferLocations:[{
type: Schema.ObjectId,
ref: 'Location'
}]
.....
});
I am using volunteer.save() method to update the model.
While updating to volunteer model i get the error as follow:
{ [DivergentArrayError: For your own good, using `document.save()` to update an
array which was selected using an $elemMatch projection OR populated using skip,
limit, query conditions, or exclusion of the _id field when the operation resul
ts in a $pop or $set of the entire array is not supported. The following path(s)
would have been modified unsafely:
preferLocations
Use Model.update() to update these arrays instead.]
message: 'For your own good, using `document.save()` to update an array which
was selected using an $elemMatch projection OR populated using skip, limit, quer
y conditions, or exclusion of the _id field when the operation results in a $pop
or $set of the entire array is not supported. The following path(s) would have
been modified unsafely:\n preferLocations\nUse Model.update() to update these a
rrays instead.',
name: 'DivergentArrayError' }
While updating the location I collect the _ids field in array and asigned to preferLocations as given below:
volunteer.preferLocations = locationIdsArray;
I don't get the error when I remove this line.What am I doing wrong?
When using $elemMatch in a projection, do not use document.save(). Instead, manually update your document using Model.update(). In your case you should try
volunteer.findOneAndUpdate(
{
_id: ObjectId("567452bae5b25d6e6c1a0f7e"),
localization: { '$elemMatch': { language: 'de' } }
},
{
$set: { 'localization.$.name' : "Neuer Name" }
}).exec(//...
});
click here more details

mongoose distinct and populate with documents

I have the following model:
var followerSchema = new Schema({
id_follower: {type: Schema.Types.ObjectId, ref: 'Users'},
id_post: {type: Schema.Types.ObjectId, ref: 'Posts'}
});
I want to be able to find all posts for a list of followers. When I use find, it returns me of course multiple times the same post as multiple users can follow the same post.
So I tried to use distinct, but I have the feeling the "populate" does not work afterwards.
Here is my code:
followerModel
.distinct('id_post',{id_follower:{$in:followerIds}})
.populate('id_post')
.sort({'id_post.creationDate':1})
.exec(function (err, postFollowers) {
console.log(postFollowers);
})
It only returns me the array of the posts, and it is not populated.
I am new to mongoDB, but according to the documentation of mongoose, the "distinct" method should return a query, just as the "find" method. And on a query you can execute the "populate" method, so I don't see what I am doing wrong.
I also tried to use the .distinct() method of the query, so then my code was like this:
followerModel
.find({id_follower:{$in:followerIds}})
.populate('id_post')
.distinct('id_post')
.sort({'id_post.creationDate':1})
.exec(function (err, postFollowers) {
console.log(postFollowers);
})
In that case it works, but as in the documentation of mongoose you need to provide a callback function when you use the distinct method on a query, and so in my logs I get errors all over. A workaround would be to have a dummy callback function, but I want to avoid that...
Does anybody has an idea why the first attempt is not working? And if the second approach is acceptable by providing a dummy callback?
Would this be the right way considering the current lack of support in mongoose?
followerModel
.find({id_follower:{$in:followerIds}})
.distinct('id_post',function(error,ids) {
Posts.find({'_id':{$in : ids}},function(err,result) {
console.log(result);
});
});
You can simply use aggregate to group and populate the collection.
now we have the desired result
db.<your collection name>.aggregate([
{
$match: {<match your fields here>}
},
{
$group: {_id: <your field to group the collection>}
},
{
$lookup: {
from: "<your collection of the poupulated field or referenced field>",
localField: "<give the id of the field which yout want to populate from the collection you matched above cases>",
foreignField: "_id", //this references the id of the document to match the localField id in the from collection
as: 'arrayName', //<some name to the returned document, this is a single document array>
}
},
{
$project: {
//you really don't want the whole populated fields, you can select the fields you want
<field name>:
<1 or 0>, // 1 to select and 0 to not select
//you can add multiple fields here
//to select the fields that just returned from the last stage we can use
"arrayName._id": <1 or 0>,
}
}
])
//at last you can return the data
.then((data) =>{
console.log(data);
});
we have distinct() by $group and
populate() by $lookup
and we also select() by $project

Resources