node.js - 有条件更新,取决于匹配的字段

标签 node.js mongodb mongodb-query

假设我有一组文档,每个文档都管理教师和学生之间的讨论:

{
    _id,
    teacherId,
    studentId,
    teacherLastMessage,
    studentLastMessage
}

我将收到包含 3 个参数的查询:_iduserIdmessage
我正在寻找一种方法来更新 teacherLastMessage 字段或 studentLastMessage 字段,具体取决于用户是谁。

目前,我有这个:

return Promise.all([

    // if user is teacher, set teacherLastMessage
    db.collection('discussions').findOneAndUpdate({
        teacherId: userId,
        _id
    }, {
        $set: {
            teacherLastMessage: message
        }
    }, {
        returnOriginal: false
    }),

    // if user is student, set studentLastMessage
    db.collection('discussions').findOneAndUpdate({
        studentId: userId,
        _id
    }, {
        $set: {
            studentLastMessage: message
        }
    }, {
        returnOriginal: false
    })


]).then((results) => {
    results = results.filter((result) => result.value);

    if (!results.length) {
        throw new Error('No matching document');
    }

    return results[0].value;
});

有没有办法告诉 mongo 根据匹配的字段进行条件更新?像这样的事情:

db.collection('discussions').findOneAndUpdate({
    $or: [{
        teacherId: userId
    }, {
        studentId: userId
    }],
    _id
}, {
    $set: {
    // if field matched was studentId, set studentLastMessage
    // if field matched was teacherId, set teacherLastMessage
    }
});

mongo 3.2 肯定可以吗?

最佳答案

您想要的内容需要引用 $set 内的其他字段。目前这是不可能的。引用this ticket举个例子。

首先,您当前使用两个更新查询的方法对我来说看起来很好。您可以继续使用它,只需确保您拥有正确的索引即可。也就是说,为了获得这些更新的最佳性能,您应该有两个复合索引:

  • { _id: 1, TeacherId: 1 }
  • { _id: 1, StudentId: 1 }.

从另一个角度来看,您可能应该重组您的数据。例如:

{
    _id: '...',
    users: [
        {
            userId: '...',
            userType: 'student',
            lastMessage: 'lorem ipsum'
        },
        {
            userId: '...',
            userType: 'teacher',
            lastMessage: 'dolor sit amet'
        }
    ]
}

这将允许您通过单个查询执行更新。

关于node.js - 有条件更新,取决于匹配的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37457393/

相关文章:

MongoDB - 降序索引奇怪的行为

c# - 使用 MongoDB 提供程序过滤多个参数

node.js - 如何使用 upworks api 创建里程碑,其 api 中定义的里程碑会出现授权错误

node.js - 在passport.js中使用req.params作为passport.authenticate()的输入(使用Express 4.0)

node.js - pm2 会杀死所有内容,并且在不重新启动服务器的情况下无法重新启动

mongodb - 获取 mongodb 中所有唯一标签的列表

node.js - 如何使用 MongoDB、Node.js(+express) 和 Jade 创建 MVC 表单

java - mongodb DAO 在 save() 之前将所有属性设置为 null

arrays - MongoDB - 使用 $elemMatch 从数组中选择多个子文档

mongodb - $exists : true (sparse indexes) 的最佳复合索引