我希望有人可以对我所拥有的这个问题有所了解,这让我疯狂到过去三天我一直在学习的东西,越来越多地了解mongoDB,但仍然无法弄清楚这个简单的查询
我需要做的是获取包含“carId”=“3C”的对象。
换句话说,我希望查询返回的对象是:
{
"carId" : "3C",
"_id" : ObjectId("51273329b64f07a40ef1c15e")
}
这是数据集(汽车):
{
"_id" : ObjectId("56223329b64f07a40ef1c15c"),
"username" : "john",
"email" : "john@john.com",
"accounts" : [
{
"_id" : ObjectId("56322329b61f07a40ef1c15d"),
"cars" : [
{
"carId" : "6A",
"_id" : ObjectId("56323329b64f07a40ef1c15e")
},
{
"carId" : "6B",
"_id" : ObjectId("56323329b64f07a40ef1c15e")
}
]
}
]
},
{
"_id" : ObjectId("56223125b64f07a40ef1c15c"),
"username" : "paul",
"email" : "paul@paul.com",
"accounts" : [
{
"_id" : ObjectId("5154729b61f07a40ef1c15d"),
"cars" : [
{
"carId" : "5B",
"_id" : ObjectId("56323329854f07a40ef1c15e")
}
]
},
{
"_id" : ObjectId("56322117b61f07a40ef1c15d"),
"cars" : [
{
"carId" : "6G",
"_id" : ObjectId("51212929b64f07a40ef1c15e")
},
{
"carId" : "3C",
"_id" : ObjectId("51273329b64f07a40ef1c15e")
},
{
"carId" : "4N",
"_id" : ObjectId("51241279b64f07a40ef1c15e")
}
]
}
]
}
请注意,我有两个嵌套数组,显然MongoDb在处理深度数组的投影方面缺乏。 $运算符只能在投影中使用一次;如何完成这个简单的任务,没有任何线索。
所以我想再次找到--only--包含“carId”的文件:“3C”并且仅返回包含“carId”的直接obj:“3C”。但不是父对象。
任何帮助都会非常感激。可能使用直接MongoDb或Mongoose。猫鼬将是首选。
至于参考,我已经涵盖了这些其他相关问题无法弄明白。
Updating a deep record in MongoDb
How to Update Multiple Array Elements in mongodb
希望将来,这个问题和你的解决方案能够帮助他人。
答案 0 :(得分:7)
阿米尔,
您必须使用Aggregation Framework。您可以构建一个管道,通过几个构建块处理流文档:过滤,投影,分组,排序等。
处理嵌套数组时,必须使用$unwind
命令。您可以通过执行以下操作获得所需内容。
db.cars.aggregate(
//De-normalized the nested array of accounts
{"$unwind": "$accounts"},
//De-normalized the nested array of cars
{"$unwind": "$accounts.cars"},
//match carId to 3C
{"$match": {"accounts.cars.carId" : "3C"}},
//Project the accoutns.cars object only
{"$project" : {"accounts.cars" : 1}},
//Group and return only the car object
{"$group":{"_id":"$accounts.cars"}}
).pretty();
您可以使用$unwind
您可以在上面的代码中删除聚合管道中每个命令底部的每一行,以观察管道行为。
答案 1 :(得分:1)
这是没有聚合框架的示例。我不认为有一种方法纯粹来自查询,你将能够得到你正在寻找的单个嵌套对象,所以你必须做一些后期处理工作。像Mongoose这样的东西可能提供了一种方法来做到这一点,但我并没有真正了解Mongoose API目前的样子。
var doc = db.cars.findOne({"accounts.cars" : {$elemMatch: {"carId" : "3C"}}}, {"accounts.cars.$": 1, _id: 0})
var car = doc.accounts[0].cars[0]