Mongoose - 在汇总

时间:2015-07-26 11:52:27

标签: node.js mongodb mongoose mongodb-query aggregation-framework

我正在构建一个聊天应用,它应该从MongoDB中检索所有新消息,并分组到对话中。但是每条消息都应该有一个新的'is_self'字段

编辑: 'is_self'字段包含一个布尔值,用于if if来自用户的消息。

所以伪:

is_self: {$cond: {if: {message.sender == MYID)}, then: true, else: false}

让我们说我有消息模型

    var MessageSchema  = new Schema({
    conversation_id:{type: mongoose.Schema.ObjectId, ref: 'Conversation', required: true},
    message: {type: String, required: true},
    sender: {type: mongoose.Schema.ObjectId, ref: 'User'},
    created: {type: Date, default: Date.now},
    read: {type: Boolean, default: false}
});

和对话模型

    var ConversationSchema = new Schema({
    from: {type: mongoose.Schema.ObjectId, ref: 'User', required: true},
    to: {type: mongoose.Schema.ObjectId, ref: 'User', required: true},
    last_changed: {type: Date, default: Date.now},
    created: {type: Date, default: Date.now}
});

现在我尝试执行聚合,加载conversation_id数组中的所有消息并创建> last_checked date ...

所以它看起来像这样:

mongoose.model("Message").aggregate([
            // First find all messages
            {
                $match: {
                    $and: [{conversation_id: {$in: idArray}}, {created: {$gt: lastChecked}}]
                }
            },
            // Add is self field
            {
                $group: {
                    _id: $_id,
                    $is_self: {
                        $cond: {'if(message.sender == MYID then true else false': '??'}
                    }
                }
            },
            // Sort by date
            {$sort: {created: -1}},

            // Then group by conversation
            {
                $group: {
                    _id: '$conversation_id',
                    messages: {
                        $push: '$$ROOT'
                    },

                }
            }
            // TODO: find users for unknown conversation
            /*,
            {
                $project: {
                    user: {
                        $or: [{conversation_id: {$in: knownConversations}}]
                    }
                }
            }*/
        ])

我尝试使用$ cond和if / else语句,但是Mongo不允许这样做..

谢谢!

1 个答案:

答案 0 :(得分:2)

简单使用返回布尔值的$eq运算符。此外,$push将采用您抛出的任何对象格式:

var senderId = // whatever;

mongooose.model("Message").aggregate([
    { "$match": {
        "conversation_id": { "$in": idArray },
        "created": { "$gt": lastChecked }
    }},
    { "$group": {
        "_id": "$conversation_id",
        "messages": {
            "$push": {
                "message": "$message",
                "is_self": { 
                    "$eq": [ "$sender", senderId ]
                }
            }
        }
    }}
    // whatever else
],function(err,results) {

})

如果您愿意,请与$cond结合使用,以交替添加" is_self"仅在检测到时:

    { "$group": {
        "_id": "$conversation_id",
        "messages": {
            "$push": {
                "$cond": [
                  { "$eq": [ "$sender", senderId] },
                  {
                    "message": "$message",
                    "is_self": true
                  },
                  {
                     "messsage": "$message" 
                  }
                ]
            }
        }
    }}