使用MongoDB检测.next()时集合的字段是否已更改

时间:2013-08-25 16:52:49

标签: mongodb

假设我有一些带有字段'State'的文档,我需要在下一个文档中检测到它的变化。为此,我想将当前光标与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()根本不起作用。关于为什么会发生这种情况的任何想法?

由于

1 个答案:

答案 0 :(得分: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