【问题标题】:How to get embedded document in an array in MongoDB (with Mongoose)如何在 MongoDB 中的数组中获取嵌入文档(使用 Mongoose)
【发布时间】:2014-04-30 00:12:12
【问题描述】:

我在 MongoDB 中保存了一个像这样的 BSON 对象:

{
  "title": "Chemistry",
  "_id": "532d665f89ae4ae703b29730",
  "__v": 0,
  "sections": [
  {
    "week": 1,
    "_id": "532d665f89ae4ae703b29731",
    "assignments": [
    {
      "created_date": "2014-03-22T10:30:55.621Z",
      "_id": "532d665f89ae4ae703b29733",
      "questions": []
    },
    {
      "created_date": "2014-03-22T10:30:55.621Z",
      "_id": "532d665f89ae4ae703b29732",
      "questions": []
    }
    ],
    "materials": []
  }
  ],
  "instructor_ids": [],
  "student_ids": []
}

我想做的是用_id 532d665f89ae4ae703b29731 检索“分配”。它是 assignments 数组中的一个元素,而后者又是sections 数组中的一个元素。

我可以通过查询检索整个文档

{ 'sections.assignments._id' : assignmentId }

但是,我想要的只是作业子文档

{
"created_date": "2014-03-22T10:30:55.621Z",
"_id": "532d665f89ae4ae703b29733",
"questions": []
}

有没有办法完成这样的查询?我应该决定在不同的集合中分配任务吗?

【问题讨论】:

    标签: javascript arrays node.js mongodb mongoose


    【解决方案1】:

    要检索数组元素的子集,您需要使用$elemMatch 投影运算符。

    db.collection.find(
        {"sections.assignments._id" : assignmentId}, 
        {"sections.assignments":{$elemMatch:{"_id":assignmentId}}}
    )
    

    注意:

    如果有多个元素匹配 $elemMatch 条件,则运算符返回数组中的第一个匹配元素。

    【讨论】:

    • 我确实使用了 $elemMatch 方法。但是,MongoDb 目前不支持 $elemMatch 2 级。
    • 我正在考虑创建另一个集合,然后使用 dbref。
    【解决方案2】:

    您可以像这样进行聚合查询:

    db.collection.aggregate(
        {$unwind: "$sections"},
        {$unwind: "$sections.assignments"},
        {$match: {"sections.assignments._id": "532d665f89ae4ae703b29731"}},
        {$project: {_id: false, assignments: "$sections.assignments"}}
    )
    

    但是,我建议您考虑创建更多集合,就像您说的那样。 在我看来,更多集合似乎是比这个查询更好的解决方案。

    【讨论】:

      【解决方案3】:

      从 mongoose 版本 6.x 开始,接受的答案不再有效,因为 $elemMatch 不能再用于嵌套文档,而是应该使用 aggregate

      如果你想使用 _id 来查找文档,你应该将作为参数获得的 _id 转换为本地 mongoDb _id 格式,否则它将被构造为字符串并会发生错误。

          const native_id = mongoose.Types.ObjectId(id);
          const assignment = await <your_model_here>.aggregate([
            { $unwind: "$sections" },
            { $unwind: "$sections.assignments" },
            { $match: { "sections.assignments._id": native_id } },
            { $project: { _id: true, sections: "$sections.assignments" } }
          ]
          )
          console.log(assignment) // you have what you want
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-20
        • 2017-01-29
        • 1970-01-01
        • 1970-01-01
        • 2011-11-10
        • 2019-02-01
        • 1970-01-01
        • 2015-02-18
        相关资源
        最近更新 更多