根据mongodb节点驱动程序文档,聚合函数现在返回一个游标(从2.6开始)。
我希望我可以使用它来获取计数的限制和跳过项目,但在创建的游标上似乎没有任何计数功能。如果我在mongo shell中运行相同的查询,则光标具有一个itcount函数,可以调用该函数以获取所需的内容。
我看到创建的游标有一个on数据事件(这意味着它是一个CursorStream吗?),它似乎被触发了预期的次数,但是如果我将它与cursor结合使用,则不会将任何结果传递给回调函数。
可以使用新的游标功能来计算聚合查询吗?
编辑代码:
在mongo shell中:
> db.SentMessages.find({Type : 'Foo'})
{ "_id" : ObjectId("53ea19af9834184ad6d3675a"), "Name" : "123", "Type" : "Foo" }
{ "_id" : ObjectId("53ea19dd9834184ad6d3675c"), "Name" : "789", "Type" : "Foo" }
{ "_id" : ObjectId("53ea19d29834184ad6d3675b"), "Name" : "456", "Type" : "Foo" }
> db.SentMessages.find({Type : 'Foo'}).count()
3
> db.SentMessages.find({Type : 'Foo'}).limit(1)
{ "_id" : ObjectId("53ea19af9834184ad6d3675a"), "Name" : "123", "Type" : "Foo" }
> db.SentMessages.find({Type : 'Foo'}).limit(1).count();
3
> db.SentMessages.aggregate([ { $match : { Type : 'Foo'}} ])
{ "_id" : ObjectId("53ea19af9834184ad6d3675a"), "Name" : "123", "Type" : "Foo" }
{ "_id" : ObjectId("53ea19dd9834184ad6d3675c"), "Name" : "789", "Type" : "Foo" }
{ "_id" : ObjectId("53ea19d29834184ad6d3675b"), "Name" : "456", "Type" : "Foo" }
> db.SentMessages.aggregate([ { $match : { Type : 'Foo'}} ]).count()
2014-08-12T14:47:12.488+0100 TypeError: Object #<Object> has no method 'count'
> db.SentMessages.aggregate([ { $match : { Type : 'Foo'}} ]).itcount()
3
> db.SentMessages.aggregate([ { $match : { Type : 'Foo'}}, {$limit : 1} ])
{ "_id" : ObjectId("53ea19af9834184ad6d3675a"), "Name" : "123", "Type" : "Foo" }
> db.SentMessages.aggregate([ { $match : { Type : 'Foo'}}, {$limit : 1} ]).itcount()
1
> exit
bye
在节点中:
var cursor = collection.aggregate([ { $match : { Type : 'Foo'}}, {$limit : 1} ], { cursor : {}});
cursor.get(function(err, res){
// res is as expected (1 doc)
});
cursor.count()不存在
cursor.itcount()不存在
存在数据事件:
cursor.on('data', function(){
totalItems++;
});
但是当与cursor.get结合使用时,.get回调函数现在包含0个文档
编辑2:返回的游标似乎是聚合游标,而不是文档中列出的游标之一
对于那些可能会搜索此内容的人来说,这可能应该得到完整的解释,因此为后代添加一个。
具体来说,返回的是用于node.js的事件流,该事件流有效地包装了stream.Readable接口,并提供了一些便捷方法。A.count()
目前不是其中之一,考虑当前使用的接口没有多大意义。
与从.stream()
游标对象可用的方法返回的结果类似,在考虑实现时,“计数”在这里没有多大意义,因为它意味着将作为“流”进行处理,最终您将到达“结束” ”,但否则只需要进行处理,直到到达那里即可。
如果您从驱动程序考虑标准的“ Cursor”接口,则有一些可靠的原因导致聚合游标不同:
游标允许在执行之前处理“修饰符”动作。这些落入的类别.sort()
,.limit()
和.skip()
。所有这些实际上在管道中指定的聚合框架中都有对应的指令。由于流水线阶段可能出现在“任何地方”,而不仅仅是作为简单查询的后处理选项,因此提供相同的“游标”处理没有多大意义。
其他光标改性剂包括特别喜欢.hint()
,.min()
和.max()
它们改变为“索引选择”和处理。尽管这些可能对聚合管道有用,但目前尚没有简单的方法将它们包括在查询选择中。通常,前一点的逻辑会覆盖对“游标”使用相同类型的接口的任何点。
其他考虑因素是您实际上想要对游标执行的操作,以及为什么您要“返回”游标。由于游标通常是“单程旅行”,即通常只处理到结束并使用可用的“批次”,因此可以得出合理的结论,即“计数”实际上实际上是在终点,实际上,“队列”最终耗尽了。
尽管事实上标准的“游标”实现确实具有一些技巧,但主要原因是这只是扩展了“元”数据概念,因为查询分析引擎必须“扫描”一定数量的文档以确定哪个文档。要返回结果的项目。
聚合框架与此概念有点关系。由于不仅存在与通过标准查询分析器处理的结果相同的结果,而且还有其他阶段。这些阶段中的任何一个都有可能“修改”实际将在要处理的“流”中返回的结果“计数”。
同样,如果您想从学术角度来看这个问题,并说“当然,查询引擎应该保留'元数据'作为计数,但是我们不能追踪之后的修改内容吗?”。这将是一个公平的论点,流水线运营商(例如$match
和$group
或$unwind
可能甚至包括$project
和new $redact
)都可以被视为合理的案例,可以在每个流水线阶段保持自己对“已处理文档”的跟踪,并在“元数据”,可能会返回以解释完整的管道结果计数。
最后一个论点是合理的,但也要考虑到目前,为聚合管道结果实现“游标”概念是MongoDB的新概念。可以合理地说,在第一个设计点时所有“合理”的期望都是合并文档的“大多数”结果的大小不会限制BSON的限制。但是随着使用范围的扩大,人们的观念也随之改变,事物也随之适应。
因此,可以“更改”此“可能”,但是“当前”实施的方式不是这样。虽然.count()
在标准的游标实现上可以访问记录了扫描编号的“元数据”,但是当前实现上的任何方法都将导致检索所有游标结果,就像.itcount()
在Shell中一样。
通过指望“数据”事件并最后发出一些内容(可能是JSON流生成器)作为“计数”来处理“光标”项。对于任何需要“前期”计数的用例,无论如何看起来都不是游标的有效用法,因为可以肯定的是,输出将是一个合理大小的整个文档。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句