mongodb - Mongoose - 填充后更新(Cast Exception)

标签 mongodb mongoose

由于 CastERror,我无法更新我的 mongoose 模式,这是有道理的,但我不知道如何解决它。

旅行模式:

var TripSchema = new Schema({
    name: String,
    _users: [{type: Schema.Types.ObjectId, ref: 'User'}]
});

用户架构:

var UserSchema = new Schema({
    name: String,
    email: String,
});

在我的 html 页面中,我呈现了一个可以向此行程添加新用户的行程,我通过调用架构上的 findById 方法检索数据:

exports.readById = function (request, result) {
    Trip.findById(request.params.tripId).populate('_users').exec(function (error, trip) {
        if (error) {
            console.log('error getting trips');
        } else {
            console.log('found single trip: ' + trip);
            result.json(trip);
        }
    })
};

这个工程找到了。在我的用户界面中,我可以将新用户添加到行程中,代码如下:

var user = new UserService();
user.email = $scope.newMail;
user.$save(function(response){   
    trip._users.push(user._id);
    trip.$update(function (response) {
        console.log('OK - user ' + user.email + ' was linked to trip ' + trip.name);

        // call for the updated document in database
        this.readOne();
    })
};

问题是,当我更新我的架构时,旅行中的现有用户被填充,意味着存储为对象而不是旅行中的 id,新用户存储为旅行中的 ObjectId。 在我更新之前,如何确保已填充的用户返回到 ObjectId?否则更新将失败并出现 CastError。

see here for error

最佳答案

我一直在寻找一种优雅的方式来处理这个问题,但没有找到令人满意的解决方案,或者至少我确信 mongoosejs 人员在使用 populate 时想到的是什么。尽管如此,这是我采取的路线:

首先,我尝试将添加到列表与保存分开。因此,在您的示例中,将 trip._users.push(user._id); 移出 $save 函数。我将这样的操作放在事物的客户端,因为我希望 UI 在我持久化之前显示更改。

其次,在添加用户时,我一直使用已填充的模型——也就是说,我没有push(user._id),而是添加了完整的用户:push (用户)。这使 _users 列表保持一致,因为其他用户的 ID 在填充期间已被替换为相应的对象。

因此,现在您应该使用一致的填充用户列表。在服务器代码中,就在调用 $update 之前,我将 trip._users 替换为 ObjectId 列表。换句话说,“取消填充”_users:

user_ids = []
for (var i in trip._users){
    /* it might be a good idea to do more validation here if you like, to make
     * sure you don't have any naked userIds in this array already, as you would
     */in your original code.
    user_ids.push(trip._users[i]._id);
}
trip._users = user_ids;
trip.$update(....

当我再次阅读您的示例代码时,看起来您要添加到行程中的用户可能是新用户?我不确定这是否只是您出于问题目的进行的简化的遗留物,但如果不是,您需要先保存用户,以便 mongo 可以在保存行程之前分配一个 ObjectId。

关于mongodb - Mongoose - 填充后更新(Cast Exception),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19411983/

相关文章:

node.js - 在 Mongoose 中,如何将子文档推送到已保存对象的数组上,然后返回我刚刚推送的内容?

mongodb - 先分组、排序、选择

javascript - 使用 Mongoose 保存

node.js - 数组中的 Mongoose 子文档虚拟

javascript - Mongoose 模式引用和未定义类型 'ObjectID'

javascript - Mongoose 为现有字段返回 undefined

node.js - Mongoose 中的子文档和嵌套对象有什么区别?

javascript - 在 MongoDb 中使用 mapReduce 获取文档(行)计数

javascript - 通过mongoose访问数组元素

javascript - 每次创建或更新后使用 mongoose 存储日志数据