我有一个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
})
似乎我可以使用数组过滤器$ []像深度嵌套那样从集合中进行更新,插入和删除,因此应该也有一种方法可以从深度嵌套的集合中仅检索单个文档。
感谢您抽出宝贵的时间来帮助:)