2013-08-25 28 views
0

假设我有一些字段为'State'的文档,我需要在下一个文档中检测它的更改。对于这一点,我想比较当前光标next()用MongoDB检测收集字段与.next()时发生变化

cursor.forEach(
     function(thisCursor){ 
      print('Current: '+thisCursor.State); 
      print('Next: '+cursor.next().State); 
     } 
) 

但输出是这样的:

Current: Florida 
Next: Florida 
Current: New Mexico 
Next: New Mexico 

所以很明显.next()是不工作的。有关为什么发生这种情况的任何想法

感谢

+0

您使用的是什么平台/编程语言? – WiredPrairie

+0

只需mongoDB javascript命令行 – Joss

回答

2

虽然你可以使用forEach通过收集迭代,你最终会跳过所有其他指数。

游标只是结果集中的一个位置。 forEach通常会将当前移动到下一个项目,但通过在光标实例上手动调用next,您可能会无意中跳过该集合。

> db.states.remove() 
> db.states.insert({name: "alabama"}) 
> db.states.insert({name: "alaska"}) 
> db.states.insert({name: "arkansas"}) 
> db.states.insert({name: "wisconsin"}) 
> db.states.insert({name: "west virginia"}) 

然后,初始化光标:

> var cursor=db.states.find(); 

如果我使用forEachnext

> cursor.forEach(function(item){ 
    print("name: " + item.name); 
    print("next name: " + cursor.next().name); }) 

它导致:

name: alabama 
next name: alaska 
name: arkansas 
next name: wisconsin 
name: west virginia 
Sun Aug 25 15:04:12.197 error hasNext: false at src/mongo/shell/query.js:124 

正如你所看到的,诅咒或者在整个集合中移动,然后,因为hasNext未被使用,所以它将步骤超出集合的长度。

您需要更改逻辑以实际读取“下一个”文档,而不会影响以下forEach循环迭代。

虽然我不明白你的数据的性质,你也许能够做这样的事情:

> var doc=cursor.hasNext() ? cursor.next() : null; 
> while(doc) { 
     var currentDoc=cursor.hasNext() ? cursor.next() : null; 
     if(currentDoc && currentDoc.name === doc.name) { 
      print("matched: " + currentDoc.name); 
     } 
     doc = currentDoc;    
    } 

它获取一个文档,然后获取下一个文件,如果有一个,并确定它到第一个。然后,通过将以前的文档与当前文档进行比较来重复。循环直到没有更多文档。

如果您的逻辑变得更复杂,我强烈建议您尝试使用Node.JS和本地MongoDB驱动程序。

此外,如果您的结果超过20个,则可能需要将批量大小设置为较大的数字。见here

相关问题