Mongo/Mongoose 无效的原子更新值错误

12

我正在尝试使用Mongoose的findOneAndUpdate函数向Mongo文档编写更新。基本上,我有一个包含另一个模式数组的文档,当我尝试添加更多这种模式类型时,我会收到以下错误:

[Error: Invalid atomic update value for $__. Expected an object, received object]

我很难理解这个错误的含义,更不用说它的来源了。

我尝试更新的数据如下:

{ section_id: 51e427ac550dabbb0900000d,
version_id: 7,
last_editor_id: 51ca0c4b5b0669307000000e,
changelog: 'Added modules via merge function.',
committed: true,
_id: 51e45c559b85903d0f00000a,
__v: 0,
modules: 
[ { orderId: 0,
type: 'test',
tags: [],
data: [],
images: [],
content: ["Some Content Here"] },
{ orderId: 1,
type: 'test',
tags: [],
data: [],
images: [],
content: ["Some Content Here"] },
{ orderId: 2,
type: 'test',
tags: [],
data: [],
images: [],
content: ["Some Content Here"] },
{ orderId: 3,
type: 'test',
tags: [],
data: [],
images: [],
content: ["Some Content Here"] },
{ orderId: 4,
type: 'test',
tags: [],
data: [],
images: [],
content: ["Some Content Here"] },
{ orderId: 5,
type: 'test',
tags: [],
data: [],
images: [],
content: ["Some Content Here"] } ] }

唯一的区别在于当我检索它时,有三个模块没有了,并且我将一些新模块添加到数组中。

很想听听任何想法,至少知道这个错误意味着什么!

6个回答

15

这可能是因为更新后的对象仍然是一个Mongoose对象。 在进行findOneAndUpdate之前尝试将其转换为JS对象。

object = object.toString()

并删除任何可能的ID属性

delete object._id
或者简单地说。
object = object.toObject();

6
你可以使用 .toObject() 方法将 mongooseObject 转换为普通对象。 - plus-
当您使用.toObject()时,它会自动删除_id字段吗? - Xsmael
谢谢你来自2020年的留言。现在世界局势很糟糕,但是你的评论对我有所帮助。 - Joost Schuur

3

我曾经遇到过相同的问题,结果发现是我在错误地使用 $push。我一直在做以下操作:

{$push:thing_to_push}

但它需要被改进。
{$push:{list_to_push_into:thing_to_push}}

3

@Magrelo和@plus给了我一个可行的答案。类似这样:

MyModel.findOneAndUpdate({ section_id: '51e427ac550dabbb0900000d' }, mongooseObject.toObject(), { upsert: true }, function(err, results) {
    //...
});

mongooseObject.toObject() 这就是帮助了,谢谢。 - Vikram

1
尝试将更新参数值作为字符串传递,而不是mongoose模型对象。当我使用模型对象传递时,我遇到了相同的错误。以下是代码差异。
存在问题的代码:
updateUser: function(req, res) {
**var updatedUserModel = new Users(req.body);**
    Users.findOneAndUpdate({tpx_id:req.params.id}, {$set:**updatedUserModel**}, function(err, User){
           ...
   }
}

工作代码:

updateUser: function(req, res) {
   Users.findOneAndUpdate({tpx_id:req.params.id}, {$set:**req.body**}, function(err, User) {
   ...
}

0
另一个需要检查的事情是,您是否正在传递一个更改数组到 $set。当调用类似以下代码时,我收到了错误消息:
db.products.update( { sku: "abc123" },
                { $set: [
                         {quantity: 500},
                         {instock: true}
                        ]
                }
              )

给了我一个错误:$set的原子更新值无效。期望是一个对象,但收到的是一个对象。

将其更改为对象后解决了问题。

db.products.update( { sku: "abc123" },
                { $set: {
                          quantity: 500,
                          instock: true
                        }
                }
              )

0

我曾经遇到过同样的问题。最终我使用了finOne()方法

如果没有找到,就创建一个新的;如果找到了,就更新现有的。

我知道这是两个操作,但我还没有找到一种可以在一步中完成它们的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接