如何在mongodb中聚合后访问特定元素?

时间:2014-09-04 20:49:12

标签: mongodb

在聚合管道之后,我得到一个对象列表,但是没有办法检索第N个对象。

请参阅:

http://docs.mongodb.org/manual/reference/operator/aggregation/group/#retrieve-distinct-values

doc的输出如下:

{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") }
{ "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") }
{ "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }

这是一组对象,但它不在列表中,因此您无法执行以下操作:

结果[1]得到第二个对象。你打算怎么和这个小组互动?

2 个答案:

答案 0 :(得分:0)

首先,如果您使用db.collection.distinct(<fieldname>)函数,您可以将字段的不同值作为数组获取:

> db.animals.distinct("call")
["moo", "baa", "woof", "meow", "quack"]

然后你可以取消引用结果,因为它是一个数组。

> calls = db.animals.distinct("call")
> calls[3]
"meow"

聚合不同的值没有db.collection.distinct()的大限制,因为它将光标返回到不同的值而不是大数组,这意味着没有16MB的BSON限制,而distinct函数可以使用索引覆盖操作。因此,当您拥有大量不同的值时,请使用聚合方法,否则使用distinct函数。虽然您可以在光标上调用.toArray()并将所有结果都放在一个数组中,但如果您有太多结果而无法使用db.collection.distinct()那么这是一个坏主意。你应该遍历游标并选择你想要的那些值并用它们做些什么:

> var k = 0
> var calls = db.animals.aggregate(<pipeline for distinct animal calls>)
> while (calls.hasNext()) {
    var call = calls.next()
    k++
    if (k == 96) doStuff(call)
}

您可以在管道中插入$skip阶段,让服务器直接跳到您想要的第一个结果,如果您还包含$sort来修复订单,结果将被返回如果你知道你只需要一定金额,你也可以使用$limit,然后.toArray()方法可能再次可行。

答案 1 :(得分:0)

在MongoDB 2.6之前,聚合方法的结果作为单个文档返回,结果放在数组中。这已更改为容纳更大的结果集,这些结果集将超过此表单限制的16MB BSON限制。现在返回的光标实际上是一个选项,但默认情况下在shell中打开。

如果您的结果不是很大,实际上有一个&#34;帮助&#34; .toArray()的方法,它通过将光标结果转换为数组来完成您想要的操作。它会在游戏中进行游标迭代,但基本上只是隐藏了你:

var results = db.collection.aggregate(pipeline).toArray()

然后只需访问该元素,它就是一个数组n-1

var result = results[8];

大多数驱动程序都可以使用类似的方法,否则驱动程序中不包含&#34;光标&#34;选项。