我想在匹配简单选择器的记录中向数组添加一个对象元素,所以我运行了这个查询:
db.eval(function() {
db.companies.find({exchange: 'OTC'}).forEach(function(c) {
c.links.push({
url: 'http://www.otcmarkets.com/stock/' + c.symbol + '/profile',
text: 'OTCMarkets.com'
});
db.companies.save(c);
});
});
在与选择器匹配的大约10,000条记录中,大约1100条记录最终在阵列末尾推送了两个链接。有什么可能导致这种情况?大约1000个有一个空的links
数组,但是大约有100个数组有一个或多个元素:
{
"_id": "...",
...
"exchange": "OTC",
"links": [
{
"text": "Website",
"url": "..."
},
{
"text": "OTCMarkets.com",
"url": "http://www.otcmarkets.com/stock/GREN/profile"
},
{
"text": "OTCMarkets.com",
"url": "http://www.otcmarkets.com/stock/GREN/profile"
}
],
"name": "GreenSmart Corp.",
...
}
大多数其他记录正确地只推送了一个数组元素:
{
"_id": "6WiXSoefPtqJdmzxa",
...
"exchange": "OTC",
...
"links": [
{
"text": "Website",
"url": "..."
},
{
"text": "Financial Information",
"url": "..."
},
{
"text": "Executives",
"url": "..."
},
{
"text": "OTCMarkets.com",
"url": "http://www.otcmarkets.com/stock/SFEF/profile"
}
],
"name": "Santa Fe Financial Corp.",
...
}
为了简洁起见,我省略了记录中的字段,但是我无法理解为什么有些人会将OTCMarkets链接元素推送一次,而其他人则会两次。
Mongo 2.6.3。
答案 0 :(得分:2)
因为你的排序:
db.companies.find({exchange: 'OTC'})
这是naural排序,并且由于您的更新很可能不适用于那些1,100,这导致一些文档移动到MongoDB内部链接列表的末尾,这是默认的排序顺序;因此,您将收到重复的文件。
使用_id或其他类似的东西对查询进行排序。
答案 1 :(得分:2)
你的问题被劫持了一些侧面讨论,但我想在答案中修正我的错误,以免误导你或其他任何人。 $isolated
运算符不会帮助您,因为它是您自己的更新,导致文档移动(因为它们更改大小),然后再次使用集合扫描重新发现。使用Sammaye建议的那种。
另外,请不要使用$isolated
,除非您确定需要单独更新;也不要忘记$isolated
更新虽然是孤立的,但不是原子的。
最后,请不要使用db.eval。它在docs中讨论了一系列限制,并且应该由聚合框架替换并执行> 1调用数据库。