【问题标题】:Error: the update operation document must contain atomic operators, when running updateOne错误:更新操作文档必须包含原子操作符,运行updateOne时
【发布时间】:2019-04-17 06:49:50
【问题描述】:

在我的收藏中,只有一个文档。

> 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

上述命令中的第二个和第三个参数来自The Definitive Guide to MongoDB: A complete guide to dealing with Big Data ... By Eelco Plugge, David Hows, Peter Membrey, Tim Hawkins中的一个例子

我的 MongoDB 是 3.2。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    第二个参数的语法错误。请查看the docs。应该是:

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

    【讨论】:

    • 我对“我不只是更新”部分感到有些困惑。您对 update 功能还有什么期望?
    • 您的意思是“替换”文档?那么你应该遵循@dyouberg 的建议并使用正确的功能。
    【解决方案2】:

    我相信这已被更改为除了 update()updateMany() 之外引入 updateOne() 方法的副作用,作为防止用户意外覆盖整个文档的某种保护措施。

    您可以改用replaceOne() 方法,或不指定multi:trueupdate()

    【讨论】:

      【解决方案3】:

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

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

      你还应该定义ObjectID,否则问题会再次出现。

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

      【讨论】:

        【解决方案4】:

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

        @Alex Blex 的回答属于 更新 类型,而 PO 试图(在 2016 年)替换。两者都是有效的,尽管它们的工作方式略有不同。

        updateX 方法在他们的第二个参数中想要一个像 Alex 的文档:{ $set: {"Type" : "DVD"... },我猜$set 是错误消息中提到的原子操作符的一个实例。
        通过更新,您可以针对数据库文档的各个属性,而其他属性保持不变。

        replace 方法将完整的文档作为第二个操作数,旨在完全替换数据库中存在的当前文档。
        在这种情况下,第二个参数只是完整的新文档。没有$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 会抱怨尝试更改不可变字段,即使该值与现有字段相同。

        【讨论】:

          【解决方案5】:

          你犯了和我一样的错误。在浏览文档后,我意识到语法是错误的。试试:

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

          【讨论】:

            猜你喜欢
            • 2016-12-17
            • 2020-03-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-20
            • 1970-01-01
            相关资源
            最近更新 更多