【问题标题】:return specific mongodb embedded document返回特定的 mongodb 嵌入文档
【发布时间】:2014-04-16 09:52:12
【问题描述】:

我想查询 mongodb 文档以返回特定文档

假设我有以下文档,我只想搜索给定房间的具体细节。比如说,我想要查询返回 room_num = 210 的注释。我该怎么做?

我可以通过 db.locations.findOne({"facility.room.room_num" : room_num}); 进行查询 我不知道如何投影房间。 概括问题,我如何仅投影嵌入文档的特定条目。

我的文档是这样的--->

{
  _id: Object("xxx"),
  name: "Campus",
  facilities: [
     { name : "Science",
     rooms : [
          {
             room_num: 210,
             notes: "Chemistry Lab 1",
             Dimension: "x*x"
          },{
             room_num: 120,
             notes: "Chemistry Lab 2",
             Dimension: "x*x"
          }
      ]

    },
    { name : "Arts",
     rooms: [
          {
             room_num: 90,
             notes: "Drawing 1",
             Dimension: "x*x"
          },{
             room_num: 100,
             notes: "Drawing 2",
             Dimension: "x*x"
          }
      ]

    }
  ]

【问题讨论】:

  • 你希望得到什么格式?
  • 我希望得到这个 {room_num: 210, notes: "Chemistry Lab 1", Dimension: "x*x" }

标签: javascript mongodb mongodb-query


【解决方案1】:

由于您有一个嵌入式数组(一个在另一个中),那么您确实可以使用聚合来做到这一点。你只需要做一个“双重”展开操作:

db.collection.aggregate([
    { "$unwind": "$facilities" },
    { "$unwind": "$facilities.rooms" },
    { "$match": { "facilities.rooms.room_num": 210 } }
])

如果你真的希望它看起来像原始文档,那就再进一步:

db.collection.aggregate([
    { "$unwind": "$facilities" },
    { "$unwind": "$facilities.rooms" },
    { "$match": { "facilities.rooms.room_num": 210 } },
    { "$group": {
        "_id": "$_id",
        "name": { "$first": "$name" },
        "facName": { "$first": "$facilities.name" },
        "rooms": { "$push": "$facilities.rooms" }
    }},
    { "$group": {
        "_id": "$_id",
        "name": { "$first": "$name" },
        "facities": { "$push": {
            "name": "$facName" ,
            "rooms": "$rooms"
        }}
    }}
])

所以根据您的数据,这将是结果:

{
    "_id" : {
            "0" : "x",
            "1" : "x",
            "2" : "x"
    },
    "name" : "Campus",
    "facities" : [
       {
           "name" : "Science",
           "rooms" : [
               {
                   "room_num" : 210,
                   "notes" : "Chemistry Lab 1",
                   "Dimension" : "x*x"
               }
           ]
       }
    ]
}

或者最后,如果您只需要数组的内部房间部分,那么只需在最后使用 $project 语句,如第一个示例所示:

db.campus.aggregate([
    { "$unwind": "$facilities" },
    { "$unwind": "$facilities.rooms" },
    { "$match": { "facilities.rooms.room_num": 210 } },
    { "$project": {
        "_id": 0,
        "room_num": "$facilities.rooms.room_num",
        "notes": "$facilities.rooms.notes",
        "Dimension": "$facilities.rooms.Dimension"
    }}
])

结果如下:

{ "room_num" : 210, "notes" : "Chemistry Lab 1", "Dimension" : "x*x" }

这应该可以清除它。

【讨论】:

  • 谢谢尼尔。我现在开始工作了。比你好多了。你为我节省了很多时间。
  • 尼尔如何仅提取设施。房间部分我的意思是房间不应该显示在设施下。我应该用我的编程语言还是 js 函数来做,从 json 中提取房间部分后只输出房间部分,同时使用 $project 禁用输出中的其他所有内容
  • 我得到了这个 { "_id" : ObjectId("534ce1af4b39df0e79064b82"), "name" : "Demo Campus", "facilities" : [ { "name" : "Demo Science Hall", " rooms" : [ { "room_num" : 210, "notes" : "Chem Lab", "last_updated" : "Tue Apr 15 2014 13:07:19 GMT+0530 (IST)" } ] } ] }
  • @jalatif 您可以在代码中重新格式化或使用管道。请参阅对此的最终编辑。
【解决方案2】:

试试下面的查询

db.locations.aggregate( 
 { $unwind: "facilities.rooms" },
 { $match: { "facilities.rooms.room_num" : room_num}},
 { $project: { "facilities.rooms.notes" : 1 }}
)

【讨论】:

  • 谢谢。我收到此错误聚合失败错误:命令失败:{“errmsg”:“异常:字段路径引用必须以'$'为前缀('facilities.rooms'”,“code”:15982,“ok”:0 }
  • 这里的项目变量有什么用? Unwind 用于在此处提取房间数组。对吗?
  • 对不起错误是我的错误。我得到了当前的结果,但我也得到了房间外的文件部分。我只想获取房间文件。
  • @Abhinav 基本上是错的。您需要有 两个 放松阶段。
【解决方案3】:

您可以使用aggregation framework。我相信 $project$unwind 运算符是您正在寻找的。

db.rooms.aggregate([{
  $project: {
    _id: 0,
    facilities: "$facilities.rooms.room_num"
  }
}, {
  $unwind: "$facilities"
}, {
  $unwind: "$facilities"
}])

你会得到类似的东西:

{
  "result" : [
    {
      "facilities" : 210
    },
    {
      "facilities" : 120
    },
    {
      "facilities" : 90
    },
    {
      "facilities" : 100
    }
  ],
  "ok" : 1
}

【讨论】:

  • $project 和双重展开的新颖用法,但鉴于对问题的评论,我确信这不是 OP 想要的。
  • 谢谢耀星。我得到了这个结果。我怎样才能只提取匹配的房间。 { room_num: 90,注释:“绘图 1”,尺寸:“x*x”}
  • @Abhinav 我已经回答了这个问题,这就是为什么我要纠正那些没有回答的人。
  • @NeilLunn 不,这不是他想要的。我在他回答我的评论之前发布了答案,因为我有点急于做别的事情。我想我至少可以向他展示一种方法,以便万一没有其他人回答,他可能会自己找到答案。但是,你们肯定提供了更好的答案。所以请忽略我的。
猜你喜欢
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 2018-08-21
  • 2017-04-02
相关资源
最近更新 更多