猫鼬更新许多包含特定数组元素的文档

时间:2020-10-20 19:25:29

标签: javascript node.js mongodb mongoose

我已经建立了一个Mongoose模式,如下所示:

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');

todos数组中的每个元素都是一个对象,并具有以下格式(示例):

{
  id: 1,
  todo: "Do the dishes."
  category: "Kitchen"
}

我的Todo集合中有多个文档,并且它们都包含相同的待办事项列表。如果我想在所有文档中更新特定的Todo,我认为我需要使用updateMany。我在Todo Update路线中使用以下命令来更新Todo的所有实例:

const { todo } = req.body; // todo.todo contains "Clean the dishes." as an update

Todo.updateMany(
  {
    todos: { $elemMatch: { id: todo.id } },
  },
  { $set: { todo: todo } }
);

我将上述路由代码的结果分配给一个变量,控制台记录返回的结果:

{ ok: 0, n: 0, nModified: 0 }

我在做什么错?传递的todo id匹配每个Todos数组中Todo的id。

1 个答案:

答案 0 :(得分:1)

首先,也建议您为对象数组创建一个模式:

const subSchema = new mongoose.Schema({
    id: Number,
    todo: String,
    category: String
})
const MongooseModel = new mongoose.Schema({
    id: String,
    todos: [subSchema],
    date: Date
})

现在,您的数组对象已定义。

而且,查询问题是这样的:

db.collection.update({
  "todos.id": todo.id
},
{
  "$set": {
    "todos.$": {newTodo}
  }
},
{
  "multi": true
})

首先,您要寻找符合条件的所有元素;即todos.id = todo.id,然后使用$运算符来设置所有与该对象匹配条件的元素。 最后一行multi将更新所有匹配的元素。

示例游乐场here

使用月光鹅,multi属性不是必需的,因为默认情况下使用true设置了updateMany()

因此,moonggose查询应该是这样的。

var update = await model.updateMany(
    {
        "todos.id": 1
    },
    {
    "$set": {
        "todos.$": {
            "id": 20,
            "todo": "newTodo",
            "category": "newCategory"
        }
    }
})

对于本示例数据,结果为

{ n: 3, nModified: 3, ok: 1 }