错误: 在运行 updateOne 时,更新操作文档必须包含原子操作符

在我的收藏中,只有一份文件。

> db.c20160712.find()
{ "_id" : ObjectId("57ab909791c3b3a393e9e277"), "Dimension_id" : 2, "Attribute" : "good", "Hour" : "20160712_06", "Frequency_count" : 100

我想运行 updateOne来用另一个文档替换这个文档。但是为什么会有 Error: the update operation document must contain atomic operators呢?

> db.c20160712.updateOne( { "Attribute" : "good"}, {"Type" : "DVD", "Title" : "Matrix, The", "Released" : 1999, "Genre" : "Action"}, { upsert: true} )
2016-08-10T16:37:57.089-0400 E QUERY    [thread1] Error: the update operation document must contain atomic operators :
DBCollection.prototype.updateOne@src/mongo/shell/crud_api.js:493:1
@(shell):1:1

上面命令中的第二个和第三个参数来自于 < a href = “ https://books.google.com/books? id = -qIvCwAQBAJ & amp; lpg = PA82 & amp; dq = The% 20final% 20guide% 20of% 20mongodb% 203ed & amp; pg = PA69 # v = onepage & amp; q & amp; f = false”rel = “ noReferrer”> 《 MongoDB 最终指南》 : 处理大数据的完整指南..。 By Eelco Plugge,David Hows,Peter Membrey,Tim Hawkins 作者: Eelco Plugge,David Hows,Peter Membrey,Tim Hawkins

我的 MongoDB 是3.2。

180695 次浏览

我相信这是由于在 update()updateMany()之外引入了 updateOne()方法的副作用而改变的,这在某种程度上是为了防止用户意外地覆盖整个文档。

可以使用 replaceOne()方法,也可以使用不指定 multi:trueupdate()方法。

第二个参数的语法错误。请检查 那些文件。它应该是:

db.c20160712.updateOne(
{ "Attribute" : "good" },
{ $set: {"Type" : "DVD", "Title" : "Matrix, The", "Released" : 1999, "Genre" : "Action" } },
{ upsert: true }
);

你应该使用这段代码,因为我也面临着同样的问题,然后我使用了这段代码:

updateOne(
{ _id: new ObjectID(req.params.id) },
{ $set: { title: req.body.bookName, author: req.body.authorName } },
{ upsert: true }
)

并且您还应该定义 ObjectID,否则问题将再次发生。

const ObjectID = require('mongodb').ObjectID;

"replaceX"方法和 "updateX"方法。

Alex Blex 给出的答案是 更新类型的,而 PO (在2016年)正在尝试通过 更换。两者都是有效的,尽管它们的作用略有不同。

UpdateX 方法在它们的第二个参数中需要像 Alex 的: { $set: {"Type" : "DVD"... }那样的文档,其中我猜想 $set是错误 msg 中提到的 原子运算符的一个实例。
通过更新,您可以针对 DB 文档的各个属性,其他属性保持不变。

更换方法将一个完整的文档作为第二个操作数,用于完全替换数据库中现有的当前文档。
在这种情况下,第二个参数就是完整的新文档。没有 $set或其他(有几个,要删除,增量,...)。

在所有情况下,第一个参数都是 MongoDB 搜索文档,在我的情况下,我使用 _id并像这样准备它:
let searchDoc = { _id: ObjectID( _id )};
正如@nagender pratap chauhan 提到的,不能使用 _id的字符串值进行匹配。
此外,与 ObjectIDObjectId(大写或小写的“ D”)也有一些混淆。

第三个参数(可选)包含选项。
updateOne方法的情况下,声明
{ upsert: true}
意味着,如果没有文档满足第一个参数中所述的搜索条件,Mongo 应该创建它。

我的代码是这样的:

let searchDoc = { _id: ObjectID( _id )};
this.data = await DAO.db.collection( 'authors' )
.replaceOne(
searchDoc,                  // filter
authorData,                 // replacement doc (a JS object)
{                           // options
returnOriginal: false,
sort: [['_id', -1]],
}
);


return this.data;               // the stored author

_id字段不能出现在替换文档中,否则 Mongo 会抱怨试图更改一个不可变字段,即使该字段的值与现有字段相同。