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

时间:2016-08-10 20:50:10

标签: mongodb

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

#!/bin/bash

echo "Running Week 1 Day 1 process programs"
. ~/.bashrc

#changing directory
cd /prod/file/sas-data2/monthly_goaling_process/macros


#run base programs needed for programs
sas 00a_libraries_and_user_information.sas
sas 00b_imports_and_macros.sas

echo "Running Historical program"
sas 01_sales_and_credit_historical_pull.sas
echo "Historical program complete"

我想运行> 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

上述命令中的第二个和第三个参数来自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。

5 个答案:

答案 0 :(得分:61)

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

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

答案 1 :(得分:15)

我认为除了updateOne()update()之外,引入updateMany()方法的副作用已被更改为防止用户意外发生的一些安全措施覆盖整个文档。

您可以改为使用replaceOne()方法,也可以使用update()而不指定multi:true

答案 2 :(得分:5)

您应该使用此代码,因为我也遇到了相同的问题,然后我使用了以下代码:

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

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

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

答案 3 :(得分:1)

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

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

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

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 会抱怨尝试更改不可变字段,即使该值与现有字段相同。

答案 4 :(得分:0)

您犯了与我相同的错误。通过文档后,我意识到语法是错误的。试试:

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