【问题标题】:Mongoose set value of nested array嵌套数组的猫鼬设置值
【发布时间】:2021-10-17 20:28:52
【问题描述】:

我正在尝试设置嵌套数组对象的值 架构:

courses: [
    {
      days: [
        {
          courseDate: {
            type: String,
          },
          attendance: {
            type: Boolean,
          },
          reason: {
            type: String,
          },
        },
      ],
      courseId: {
        type: String,
      },
      name: {
        type: String,
      },
      startTime: {
        type: String,
      },
      endTime: {
        type: String,
      },
    },
  ],

这是我的尝试:

await Student.findOneAndUpdate(
      { "courses.days._id": "6117b0c45345db20f0dc3336" },
      { $set: { "courses.$.days.$.attendance": true } },
      { new: true }
    );

    await Student.findOneAndUpdate(
      { "courses.days._id": req.params.dayId },
      { "courses.$[courseIndex].days.$[dayIndex].attendance": true },
      {
        arrayFilters: [
          {
            courseIndex: req.params.courseId,
          },
          {
            dayIndex: req.params.dayId,
          },
        ],
      }
    );

这是文件:

 "courses" : [ 
        {
            "_id" : ObjectId("6117b0c45345db20f0dc3330"),
            "courseId" : "61155838b1fff211dd9a8765",
            "name" : "succ",
            "startTime" : "20:20",
            "endTime" : "23:20",
            "days" : [ 
                {
                    "_id" : ObjectId("6117b0c45345db20f0dc3331"),
                    "courseDate" : "Wed Aug 04 2021 00:00:00 GMT+0300 (Israel Daylight Time)",
                    "attendance" : false,
                    "reason" : ""
                }, 
                {
                    "_id" : ObjectId("6117b0c45345db20f0dc3332"),
                    "courseDate" : "Wed Aug 11 2021 00:00:00 GMT+0300 (Israel Daylight Time)",
                    "attendance" : false,
                    "reason" : ""
                }, 
                {
                    "_id" : ObjectId("6117b0c45345db20f0dc3333"),
                    "courseDate" : "Wed Aug 18 2021 00:00:00 GMT+0300 (Israel Daylight Time)",
                    "attendance" : false,
                    "reason" : ""
                }, 
                {
                    "_id" : ObjectId("6117b0c45345db20f0dc3334"),
                    "courseDate" : "Wed Aug 25 2021 00:00:00 GMT+0300 (Israel Daylight Time)",
                    "attendance" : false,
                    "reason" : ""
                }
            ]
        }, 
        {
            "_id" : ObjectId("6117b0c45345db20f0dc3335"),
            "courseId" : "61155838b1fff211dd9a8765",
            "name" : "test",
            "startTime" : "13:40",
            "endTime" : "15:40",
            "days" : [ 
                {
                    "_id" : ObjectId("6117b0c45345db20f0dc3336"),
                    "courseDate" : "Thu Aug 05 2021 00:00:00 GMT+0300 (Israel Daylight Time)",
                    "attendance" : false,
                    "reason" : ""
                }, 
                {
                    "_id" : ObjectId("6117b0c45345db20f0dc3337"),
                    "courseDate" : "Thu Aug 12 2021 00:00:00 GMT+0300 (Israel Daylight Time)",
                    "attendance" : false,
                    "reason" : ""
                }, 
                {
                    "_id" : ObjectId("6117b0c45345db20f0dc3338"),
                    "courseDate" : "Thu Aug 19 2021 00:00:00 GMT+0300 (Israel Daylight Time)",
                    "attendance" : true,
                    "reason" : ""
                }, 
                {
                    "_id" : ObjectId("6117b0c45345db20f0dc3339"),
                    "courseDate" : "Thu Aug 26 2021 00:00:00 GMT+0300 (Israel Daylight Time)",
                    "attendance" : false,
                    "reason" : ""
                }
            ]
        }
    ],

第一个是抛出错误:

Too many positional (i.e. '$') elements found in path 'courses.$.days.$.attendance'

第二个不起作用...我真的不明白第二种方法的问题在哪里。

它找到了正确的文档,但它没有更新任何东西。

需要注意的是,每个数组的位置都是动态的,所以第二种方法也很好。

【问题讨论】:

  • 确保对req.params 变量进行类型转换。默认情况下,它们是字符串类型。
  • 还是不行:(
  • 类型转换"courses.days._id": ObjectId(req.params.dayId)。看我的回答
  • 这能回答你的问题吗? arrayFilters in mongodb

标签: node.js mongodb mongoose


【解决方案1】:

过滤的位置运算符 $[] 标识与更新操作的 arrayFilters 条件匹配的数组元素。

{ <update operator>: { "<array>.$[<identifier>]" : value } },
{ arrayFilters: [ { <identifier>: <condition> } ] }

如果identifier 是一个对象,我们可以在arrayFilters 条件下进一步查询该对象。

由于 arrayFilters 是与 mongodb 相关的东西,你需要在 mongoose 中使用 ObjectId 转换 id

    await Student.findOneAndUpdate(
      { 
        "courses": { "$elemMatch": { "_id": ObjectId(req.params.courseId)} }, 
        "courses.days": { "$elemMatch": { "_id": ObjectId(req.params.dayId)} } 
      },
      { "courses.$[courseIndex].days.$[dayIndex].attendance": true },
      {
        arrayFilters: [
          {
            courseIndex._id: ObjectId(req.params.courseId),
          },
          {
            dayIndex._id: ObjectId(req.params.dayId),
          },
        ],
        new: true,
      }
    );

编辑:
您需要使用new: true 来获取更新后的值

【讨论】:

  • Gaurav Sharma 它仍然不起作用....只是确保。 req.params.dayId 和 req.params.courseId 是每个元素的id。它们不是索引
  • @DavidAxelrod Ohh.. 我以为它们是数组的索引
  • 非常感谢!!!对此,我真的非常感激!!!!但是你能解释一下为什么在过滤器中写成 ._id 吗?只有 courseIndex?
  • 嗨@Gaurav Sharma 我想投票 :) 但我收到了这条消息:感谢您的反馈!您需要至少 15 声望才能投票,但您的反馈已被记录。我可以通过其他方式提供帮助吗?
  • 感谢@DavidAxelrod,我们互相学习。继续为社区做出贡献。这就是我想要的:)
猜你喜欢
  • 2018-10-30
  • 2019-11-15
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 2021-04-14
  • 2013-11-24
相关资源
最近更新 更多