提问者:小点点

MongoDB无法更新文档,因为_id是字符串,而不是ObjectId


我正在做一个rest api来在mongo数据库和web应用程序之间交换数据。这些数据是json格式的。

我在更新文档时遇到一个麻烦:

cannot change _id of a document.

事实上,在我的JSON中,doc的id存储为字符串,并反序列化为字符串。而在Mongo中则存储为ObjectID。这就解释了为什么mongo会引发错误。

  • 在mongo:_id:ObjectId('51051FD25B442A5849000001')
  • 在JSON:_ID:“51051FD25B442A5849000001”

为了避免这种情况,我手动将_id属性从string转换为ObjectId。但它看起来很难看,而且会在其他BSON类型中失败。

问:有没有一个干净的方法来避免这种情况,或者做一个很好的JSON/BSON转换?

下面是我用来更新文档的代码。我将nodejs与express一起使用,将mongodb与本机驱动程序一起使用。

exports.updateById = function(req, res) {
var id = req.params.id;
var map = req.body;

map._id = new ObjectID.createFromHexString( map._id); // Manual conversion. How to avoid this???

console.log( 'Updating map: ' + id);
console.log( 'Map: ' + JSON.stringify( map));

db.collection('maps', function(err, collection) {
    if(err) throw err;
    collection.update(
        {'_id': new BSON.ObjectID(id)}, map, {safe:true}, 
        function(err, result) {
            if (err) {
                console.log('Updating map err: ' + JSON.stringify( err));
                res.json( 500, {'message':'An error has occurred while updating the map', 'error': err});
            } else {
                console.log('Updating succeed');
                res.send(map);
            }
        }
    );
});

};


共1个答案

匿名用户

因为您不能修改_id字段,所以更好的方法是简单地从map对象中删除该字段,而不是将其转换为ObjectId。

所以这个:

delete map._id;

而不是这样:

map._id = new ObjectID.createFromHexString( map._id);

如果您希望像使用res.send(map);那样返回更新后的对象,则应该使用findandmodify而不是update,这样您就可以访问生成的文档,而不仅仅是发布的文档。