【发布时间】:2015-01-14 07:17:41
【问题描述】:
假设我有一个如下的对象数组。
"array" : [
{
"id" : 1
},
{
"id" : 2
},
{
"id" : 2
},
{
"id" : 4
}
]
如果我想从这个数组中检索多个对象({id : 2}),聚合查询是这样的。
db.coll.aggregate([{ $match : {"_id" : ObjectId("5492690f72ae469b0e37b61c")}}, { $unwind : "$array"}, { $match : { "array.id" : 2}}, { $group : { _id : "$_id", array : { $push : { id : "$array.id"}}}} ])
上述聚合的输出是
{
"_id" : ObjectId("5492690f72ae469b0e37b61c"),
"array" : [
{
"id" : 2
},
{
"id" : 2
}
]
}
现在的问题是: 1) 是否可以在 MongoDB 中使用 find() 从数组中检索 多个对象?
2) 关于性能,聚合是正确的做法吗? (因为我们需要使用四个管道操作符)?
3) 我们可以使用 Java 操作(循环数组并只保留 {id : 2} 个对象)来执行此操作 find({"_id" : ObjectId("5492690f72ae469b0e37b61c")}) 查询?因为 find 将检索文档并将其保存在 RAM 中。但是如果我们使用聚合,则需要在 RAM 中执行四个操作才能获得输出。
为什么我问 3) 的问题是:假设如果有数千个客户端同时访问,那么 RAM 内存将会过载。如果使用 Java 完成,RAM 上的任务会更少。
4) workingSet 将在 RAM 中保留多长时间??
我的理解正确吗???
如果我错了,请纠正我。
请建议我对此有正确的见解..
【问题讨论】:
-
每个问题 1 个问题。这就是它的工作原理。不,没有其他方法可以使用
.find()过滤数组。聚合框架是实现此目的的工具。请将您的其他问题作为单独的问题提出。问题 4 属于 dba.stackexchange.com -
并注意点“3”,就好像你没有聚合任何东西或者在其他一些后期阶段需要它,那么你最好在客户端过滤你的数组。这一切都取决于规模。
-
聚合比 find() 慢。这就是我问问题3)的原因。那么什么是正确的方法。 find()+Java 还是聚合()?
-
当然聚合速度较慢,您正在操作文档,这就是您使用它的原因。我的意思是,如果您的唯一意图是过滤掉匹配的
"id": 2条目并且数组相对较小,那么在使用.find()检索整个文档后在客户端上执行此操作。 -
正确的方法归结为测试。我们并不真正了解这些数据是否可以被其他实体重用:将其存储在 RAM 客户端是否有用。通常,聚合框架用于获取数据的每个连接视图,从长远来看,这将比在客户端进行操作更快。请记住,聚合中的4个操作也可以导致客户端代码中的近4个,请记住客户端也需要过滤
标签: mongodb mongodb-query aggregation-framework