【问题标题】:mongodb field of array type won't update length when using .push()使用 .push() 时,数组类型的 mongodb 字段不会更新长度
【发布时间】:2017-06-06 02:53:27
【问题描述】:

下面是尝试将用户添加到架构的代码:

var roomSchema = new Schema({
    name: { type: String, required: true},
    connections: { type: [ { userId: String } ] },
    content: { type: String, default: ""},
    isFull: { type: Boolean, default: false}
});

roomSchema.methods.addUser = function(username, callback) {
this.updateAsync( { $push: { connections: { userId: username }  } } )
.then(function(status) {
    return this.saveAsync();
})
.catch(function(afterPushErr) {
    console.log('After push error');
    throw afterPushErr;
})
.catch(function(saveErr) {
    console.log('save Error');
    throw saveErr;
});

Promise.all(this.connections)
.then(function() {
    if(this.connections.length >= 5) {
        this.updateAsync( { isFull: true })
        .then(function(status) {
            return;
        })
        .catch(function(updateErr) {
            console.log('update Error!');
            throw updateErr;
        });
    }
});

}

然后是调用它的代码(正确导入上述函数): (注意:这只是一个快速测试功能,以确保每个房间最多只能有 5 个用户)

var populateRooms = function() {
    var names = [
        'asas',
        'asas2',
        'asas3',
        'asas4',
        'asas5',
        'asas6'];

    var emails = [
        'asas@as.ca',
        'asas2@as.ca',
        'asas3@as.ca',
        'asas4@as.ca',
        'asas5@as.ca',
        'asas6@as.ca'];

    for(var i=0; i<6; ++i) {
    Room.findOneAsync( { isFull: false })
        .then(function(freeRoom) {
            var newUser = new User({
                username : names[i],
                email : emails[i],
                password : 'Asasas1',
                isPlaced: true,
                roomName: freeRoom.name
            });
            freeRoom.addUser(newUser.username);
            return newUser;
        })
        .then(function(newUser) {
            newUser.saveAsync();
        })
        .catch(function(err) {
            throw err;
        });
    }
    return true;
}

通常我将在控制台中看到的只是被推送的最后一个用户,而不是整个列表,因此我无法查看列表的长度是否 >= 5。

在 mongo 控制台上,我看到了房间模式:

{ "_id" : ObjectId("5882c3eefab3081700444972"), "name" : "1484964846968_0", "isFull" : false, "content" : "", "connections" : [ { "userId" : "asas5", "_id" : ObjectId("5882c3effab308170044497f") }, { "userId" : "asas6", "_id" : ObjectId("5882c3effab308170044497d") }, { "userId" : "asas4", "_id" : ObjectId("5882c3effab3081700444981") }, { "userId" : "asas6", "_id" : ObjectId("5882c3effab308170044497d") }, { "userId" : "asas5", "_id" : ObjectId("5882c3effab308170044497f") }, { "userId" : "asas4", "_id" : ObjectId("5882c3effab3081700444981") }, { "userId" : "asas3", "_id" : ObjectId("5882c3effab3081700444983") }, { "userId" : "asas", "_id" : ObjectId("5882c3effab3081700444987") }, { "userId" : "asas2", "_id" : ObjectId("5882c3effab3081700444985") }, { "userId" : "asas3", "_id" : ObjectId("5882c3effab3081700444983") }, { "userId" : "asas2", "_id" : ObjectId("5882c3effab3081700444985") }, { "userId" : "asas", "_id" : ObjectId("5882c3effab3081700444987") } ], "__v" : 12 } { "_id" : ObjectId("5882c3eefab3081700444973"), "name" : "1484964846978_1", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444974"), "name" : "1484964846980_2", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444975"), "name" : "1484964846980_3", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444976"), "name" : "1484964846981_4", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444977"), "name" : "1484964846981_5", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444978"), "name" : "1484964846982_6", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab3081700444979"), "name" : "1484964846984_7", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab308170044497a"), "name" : "1484964846984_8", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 } { "_id" : ObjectId("5882c3eefab308170044497b"), "name" : "1484964846984_9", "isFull" : false, "content" : "", "connections" : [ ], "__v" : 0 }

编辑 这是 addUser 的承诺代码的新错误

(node:4648) UnhandledPromiseRejectionWarning: 未处理的承诺 拒绝(拒绝 id:1):TypeError:无法读取属性 未定义的“连接”(节点:4648) UnhandledPromiseRejectionWarning:未处理的承诺拒绝 (拒绝 id:2):TypeError:无法读取属性“连接” undefined 推送错误后 推送错误保存后 错误保存 错误 未处理的拒绝类型错误:无法读取属性“saveAsync” 不明确的 在 C:\someApp\app\models\room-model.js:19:14 在 tryCatcher (C:\someApp\node_modules\bluebird\js\release\util.js:16:23)

【问题讨论】:

    标签: javascript node.js mongodb


    【解决方案1】:

    在测试函数中,将异步调用(Room.findOne) 放在 for 循环中。因此,每个循环都得到相同的freeZoom。(这不是你想要的)

    检查这个问题:Asynchronous Process inside a javascript for loop

    另一个建议,addUser 函数内的this.update 也是异步的,在某些情况下可能不像您想要的那样。

    【讨论】:

    • 所以关键是前5个查询将返回相同的;并在他们找到房间后添加用户并保存房间和用户。
    • 最后的第一个房间有6个用户,这意味着唯一缺少的是当房间满员时(那里有5个人)推送的停止点。
    • 也许你可以使用猫鼬查询作为promises,而不是回调样式。
    • 所以我能够让脚本异步添加用户(大概是这样我将编辑上面的代码以反映这一点。但是看起来错误的核心是 addUser 函数并确保一切都按顺序发生。我还将显示新代码以反映这些更改,我收到一个新错误:无法保存未定义的属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    相关资源
    最近更新 更多