尝试从深度嵌套的集合中投影单个文档

时间:2019-02-10 19:31:39

标签: mongodb

我有一个MongoDB集合,其中包含深层嵌套的文档。具体来说,我的层次结构如下:客户>项目>房间。

我的目标是能够使用clientId,projectId和roomId来过滤和投影此集合,以便仅从数据库返回所需的房间。房间可能附加了许多日志和其他数据元素,将它们全部拉回并用客户端代码过滤似乎很浪费。

我想避免将集合拆分为多个集合。

我不使用像猫鼬等的ORM,并且从现在开始,我想将它们排除在外,因为这在很大程度上是一种学习练习,可以提高我的MongoDB技能。

我尝试使用projection $运算符,该运算符对于第一层嵌套数组效果很好

具有以下数据结构:

{ 
    "_id" : ObjectId("5c3a3fc7e72812c33ed9a0b9"), 
    "clienttype" : "Residential", 
    "name" : "Bob", 
    "projects" : [
        {
            "_id" : ObjectId("5c3a3fc7e72812c33ed9a0ba"), 
            "name" : "First Project", 
            "rooms" : [
                {
                    "_id" : ObjectId("5c5f1a9d354c541edd2eac8e"), 
                    "name" : "Room 1", 
                }, 
                {
                    "_id" : ObjectId("5c5f1d6b354c541edd2eac8f"), 
                    "name" : "Room 2", 
                }
            ]
        }, 
        {
            "_id" : ObjectId("5c3a3fc7e72812c33ed9a0bb"), 
            "name" : "Second Project", 
            "rooms" : [
                {
                    "_id" : ObjectId("5c5f1da6354c541edd2eac96"), 
                    "name" : "Room 3", 
                }
            ]
        }
    ]
}

我能够成功运行此查询:

  db.getCollection("clients").find({
   "_id": ObjectId("5c3a3fc7e72812c33ed9a0b9"),
   "projects._id": ObjectId("5c3a3fc7e72812c33ed9a0ba")
  },
  {
    "projects.$":1
  })

我遇到麻烦的地方如下...

使用多个位置运算符(显然不允许):

db.getCollection("clients").find({
   "_id": ObjectId("5c3a3fc7e72812c33ed9a0b9"),
   "projects._id": ObjectId("5c3a3fc7e72812c33ed9a0ba"),
   "projects.rooms._id": ObjectId("5c5f1d6b354c541edd2eac8f")
  },
  {
    "projects.$.rooms.$":1
  })

尝试省略第一个$,如SO上的一些答案所指示,它已执行,但未能过滤room集合:

db.getCollection("clients").find({
   "_id": ObjectId("5c3a3fc7e72812c33ed9a0b9"),
   "projects._id": ObjectId("5c3a3fc7e72812c33ed9a0ba"),
   "projects.rooms._id": ObjectId("5c5f1d6b354c541edd2eac8f")
  },
  {
    "projects.rooms.$":1
  })

似乎我可以使用数组过滤器$ []像深度嵌套那样从集合中进行更新,插入和删除,因此应该也有一种方法可以从深度嵌套的集合中仅检索单个文档。

感谢您抽出宝贵的时间来帮助:)

0 个答案:

没有答案