我正在尝试使用文档数组作为参数调用 mongodb 的 db.collection.save 方法。如果 _id 存在,我想进行批量操作插入/替换。
这是我的测试用例:
> use sometestdb
switched to db sometestdb
>
> doc1 = { _id: 1, value: "some value 1" }
{ "_id" : 1, "value" : "some value 1" }
> doc2 = { _id: 2, value: "some value 2" }
{ "_id" : 2, "value" : "some value 2" }
> doc3 = { _id: 3, value: "some value 3" }
{ "_id" : 3, "value" : "some value 3" }
>
> db.docs.save( [doc1, doc2, doc3] )
>
> doc1 = { _id: 1, value: "some value 1 - updated" }
{ "_id" : 1, "value" : "some value 1 - updated" }
> doc2 = { _id: 2, value: "some value 2 - updated" }
{ "_id" : 2, "value" : "some value 2 - updated" }
> doc3 = { _id: 3, value: "some value 3 - updated" }
{ "_id" : 3, "value" : "some value 3 - updated" }
> db.docs.save( [doc1, doc2, doc3] )
E11000 duplicate key error index: sometestdb.docs.$_id_ dup key: { : 1.0 }
如果我尝试调用 db.docs.save (doc1)
,db.docs.save (doc2)
则不会抛出任何错误。谢谢。
最佳答案
MongoDB 不支持在一次调用中批量更新多个文档。虽然行为可能看起来不寻常,但控制台的 JavaScript 正在部分尝试准确执行您的要求,即使我怀疑这是无意的,因为在第一种情况下使用 insert
会更有效。
当你:
db.docs.save( [doc1, doc2, doc3] )
MongoDB 遍历数组并创建每个文档:
> db.docs.find()
{ "_id" : 1, "value" : "some value 1" }
{ "_id" : 2, "value" : "some value 2" }
{ "_id" : 3, "value" : "some value 3" }
如果您要重复此操作,您会发现:
> db.docs.save([doc1,doc2,doc3])
E11000 duplicate key error index: test.docs.$_id_ dup key: { : 1.0 }
这至少有部分意义,因为您不能在集合中插入
两次相同的文档:
> db.docs.insert(doc1)
E11000 duplicate key error index: test.docs.$_id_ dup key: { : 1.0 }
由于 MongoDB 中没有针对多个文档的高效“批量”更新(您可以一次更新多个文档,这些文档都匹配单个查询,但您不能通过传入数组来更新单个文档,至少通过控制台是这样).
save
只是一个围绕更新的辅助方法,因为它从文档中提取 _id
并将其传递给 update
。
因此,虽然他们可以将功能作为一种便捷方法添加到控制台支持中,但底层 MongoDB 数据库仍然无法直接支持该操作,因此它仍将单独执行这些操作。一些驱动程序已经支持这一点——但它是逐个完成的,而不是成批完成的。
你想要的行为的等价物无论如何都可以写在一行中:
[doc1, doc2, doc3].forEach(function(d) { db.docs.save(d) })
关于mongodb - 当我尝试对文档数组执行 db.collection.save 操作时,Mongo 抛出 E11000 重复键错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19787803/