如果有两个嵌套的 cursor.forEach()
函数,则第二个函数不会被执行。 while
循环也会发生同样的情况:
我想从一个巨大的集合中删除重复项,方法是将文档移动到另一个集合,并检查重复项是否已存在。我在 mongo shell 中运行以下代码:
var fromColl = db.from.find(),
toColl;
fromColl.forEach(function(fromObj){
toColl = db.to.find({name: fromObj.name});
if (toColl.length() == 0) {
//no duplicates found in the target coll, insert
db.to.insert(fromObj);
} else {
//possible duplicates found in the target coll
print('possible duplicates: ' + toColl.length());
toColl.forEach(function(toObj){
if (equal(fromObj.data, toObj.data)) {
//duplicate...
}
});
}
});
在 else block 中,打印了 toColl.length()
,但不执行第二个 forEach 循环。有谁知道为什么吗?
最佳答案
--- 解决方法 ---
我找到了一个解决方法,并创建了第二个光标的数组:toColl = db.to.find({name: fromObj.name}).toArray();
并且我迭代了该数组使用普通的 JS for 循环:
var fromColl = db.from.find(),
toColl,
toObj;
fromColl.forEach(function(fromObj){
toColl = db.to.find({name: fromObj.name}).toArray();
if (toColl.length == 0) {
//no duplicates found in the target coll, insert
db.to.insert(fromObj);
} else {
//possible duplicates found in the target coll
print('possible duplicates: ' + toColl.length());
for (var i = 0; i < toColl.length; i++) {
toObj = toColl[i];
if (equal(fromObj.data, toObj.data)) {
//duplicate...
}
});
}
});
--- 更新 ---
正如斯蒂芬·斯坦内克指出的那样:
mongo shell 有一些在 shell 中处理数据的快捷方式。 MongoDB 文档对此进行了更详细的解释:Iterate a Cursor in the mongo Shell .
特别是:
if the returned cursor is not assigned to a variable using the var keyword, then the cursor is automatically iterated up to 20 times to print up to the first 20 documents in the results.
在代码示例中,toColl
的 var
声明是在执行 find()
之前进行的。
使用 toArray() 迭代所有结果是一种可能的方法,但需要将游标返回的所有文档加载到 RAM 中。手动迭代光标是一种更具可扩展性的方法。
-- 解决方案 --
主要问题是使用 toColl.length()
而不是 toColl.count()
。
因为toColl.length()
重置了光标。
非常感谢 MongoDB user group 的 Rhys Campbell 和 Stephen Steneker帮助解决此错误。
关于javascript - MongoDB shell : nested iteration through cursors not executing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44483463/