我是MongoDB的新手,并且在为我正在开发的新项目设置特定查询时遇到了一些困难。
我的数据结构看起来像这样(简化版):
games: {_id: ..., scenes: [{_id: ..., views: [{_id: ...}]}]}
(即游戏包含一系列场景,场景包含一组视图)。
我想在这里查询的是一个特定的视图对象。我想答案是使用$ elemMatch,但我该如何设置呢?经过一些研究+游戏后,我知道我可以这样做以获得现场:
db.collection("games").findOne({
_id: ObjectId(req.params.gid)},
{
scenes: {
$elemMatch: {_id: ObjectId(req.params.sid)}
}
}...
但是如何扩展它以便它只能拉出我感兴趣的特定视图(通过_id)?
我想我总是可以使用for循环找到我正在寻找的视图对象,这带来了另一个问题。 Wrt性能,最好是使用Mongo进行这样的查询,还是通过拉动整个文档循环收集来手动?
答案 0 :(得分:1)
如果您的集合不大,并且此操作相对较少,那么使用聚合框架进行此操作可能会很好。但是,如果此操作频繁且对性能至关重要,那么我会说应用程序级查询。无论如何,这就是你使用聚合和$unwind
:
所以如果这是你的收藏品:
> db.col.find().pretty()
{
"_id" : ObjectId("57e6a5404897ec06f1c3d86f"),
"games" : [
{
"_id" : "game1",
"scenes" : [
{
"_id" : "scene1",
"views" : [
{
"_id" : "view1"
}
]
}
]
}
]
}
{
"_id" : ObjectId("57e6a5d24897ec06f1c3d870"),
"games" : [
{
"_id" : "game1",
"scenes" : [
{
"_id" : "scene11",
"views" : [
{
"_id" : "view111"
},
{
"_id" : "view112"
},
{
"_id" : "view113"
}
]
},
{
"_id" : "scene12",
"views" : [
{
"_id" : "view121"
}
]
}
]
},
{
"_id" : "game2",
"scenes" : [
{
"_id" : "scene21",
"views" : [
{
"_id" : "view211"
}
]
}
]
}
]
}
让我们说你想找到ID为"view112"
的视图,你可以这样做:
db.col.aggregate([
{ $unwind: "$games"},
{ $unwind: "$games.scenes"},
{ $unwind: "$games.scenes.views"},
{
$match: {
"games.scenes.views._id": "view112"
}
}
])
你会得到:
{
"_id": ObjectId("57e6a5d24897ec06f1c3d870"),
"games": {
"_id": "game1",
"scenes": {
"_id": "scene11",
"views": {
"_id": "view112"
}
}
}
}
答案 1 :(得分:0)
我没有得到它,您可以直接查询
db.collection("games").findOne({"scenes.views._id":ObjectId(req.params.vid)},{_id:0,"scenes.$.views":1});
它应该从场景中删除其他场景(双关语)。但是,它仍然会为您提供多个视图,因为$只能在任何表达式中使用一次。在那里,我认为循环是关键。
我建议反对聚合,它们很昂贵。至于用查询来实现这个或者获取文档并循环遍历它。我肯定会通过查询来实现它,你获取的数据越少,性能就越好。