有条件的更新,取决于匹配的字段

假设我有一个文件集合,每个文档pipe理一个老师和一个学生之间的讨论:

{ _id, teacherId, studentId, teacherLastMessage, studentLastMessage } 

我将得到3个参数的查询:一个_id ,一个userId和一个message
我正在寻找一种方法来更新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其他字段。 这目前是不可能的。 以这张票为例。

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

  • { _id: 1, teacherId: 1 }
  • { _id: 1, studentId: 1 }

要从另一个angular度来看待这个问题,你应该重组你的数据。 例如:

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

这将允许您使用单个查询执行更新。

你的数据结构有点奇怪,除非你有一个特定的商业案例,要求数据被模仿,我会build议创build一个用户types,除非用户既可以是老师也可以是学生,然后保持你的结构。

$set{}参数可以接受一个对象,我的build议是先做好你的业务逻辑。 如果更新是针对教师或学生的,您应该已经知道更新之前 – 应设置某种variables/authentication级别来区分教师和学生。 也许在callback中成功login,你可以设置一个cookie /本地存储。 无论如何 – 如果你有当前types的用户,那么你可以更早地build立你的对象,所以根据用户types使用你需要的属性来创build一个对象。 所以

 if(student) { var updateObj = { studentLastMsg: msg } } else { var updateObj = { teacherLastMsg: msg } } 

然后通过你的更新$set{updateObj}我将这个片段 – 在手机上