Reputation: 125
I've got a Mongoose
schema set up as follows:
const mongoose = require('mongoose');
const TodoSchema = mongoose.Schema({
id: {
type: String,
required: true,
},
todos: {
type: Array,
required: true,
},
date: {
type: Date,
default: Date.now(),
},
});
module.exports = mongoose.model('todo', TodoSchema, 'todos');
Each of the elements in the todos
Array is an Object and has the following format (example):
{
id: 1,
todo: "Do the dishes."
category: "Kitchen"
}
There are multiple documents in my Todo
collection and they all contain the same list of Todos. If I wanted to update a specific Todo across ALL documents, I figure I need to use updateMany
. I'm using the following in my Todo Update route to update all instances of a Todo:
const { todo } = req.body; // todo.todo contains "Clean the dishes." as an update
Todo.updateMany(
{
todos: { $elemMatch: { id: todo.id } },
},
{ $set: { todo: todo } }
);
I'm assigning the result of the above route code to a variable and console logging the result which comes back with:
{ ok: 0, n: 0, nModified: 0 }
What am I doing wrong? The passed todo
id matches the id of a Todo in each of the Todos
arrays.
Upvotes: 0
Views: 3321
Reputation: 15187
First of all, for your object array, is recommendable create a schema too:
const subSchema = new mongoose.Schema({
id: Number,
todo: String,
category: String
})
const MongooseModel = new mongoose.Schema({
id: String,
todos: [subSchema],
date: Date
})
So now, your array object is defined.
And, the query question is something like that:
db.collection.update({
"todos.id": todo.id
},
{
"$set": {
"todos.$": {newTodo}
}
},
{
"multi": true
})
First, you look for all elements that match your criteria; that is: todos.id = todo.id
, then you use $
operator to set all element that match the criteria with your object.
The last line multi
is to updated all element that match.
Example playground here
Using moongoose, multi
attribute is not neccessary because is set true
by default using updateMany()
.
So moongose query should be something like that.
var update = await model.updateMany(
{
"todos.id": 1
},
{
"$set": {
"todos.$": {
"id": 20,
"todo": "newTodo",
"category": "newCategory"
}
}
})
And for this example data the result is
{ n: 3, nModified: 3, ok: 1 }
Upvotes: 1