javascript - 嵌套值的 $sum 内的 $nin 条件
问题描述
我正在使用nodejs
and制作聊天应用程序mongodb
。目前我有多个用户、房间和消息的集合。每条消息都包含对房间、发件人的引用以及对已阅读该消息的用户的引用数组。
我正在尝试使用 mongodb 的聚合来获取当前用户的未读消息计数。这是我当前的代码:
Room.aggregate([
{
$match: { participants: request.currentUser._id },
},
{
$lookup: {
from: 'messages',
localField: '_id',
foreignField: 'room',
as: 'messages',
},
},
{
$unwind: {
path: '$messages',
preserveNullAndEmptyArrays: true,
},
},
{
$sort: { 'messages.createdAt': -1 },
},
{
$group: {
_id: '$_id',
name: { $first: '$name' },
type: { $first: '$type' },
participants: { $first: '$participants' },
latestMessage: { $first: '$messages' },
createdAt: { $first: '$createdAt' },
updatedAt: { $first: '$updatedAt' },
unreads: {
$sum: {
$cond: {
if: {
$nin: [request.currentUser._id, '$messages.read']
}
}
}
},
},
},
])
此代码总是抛出Unrecognized expression '$nin'
错误。我怎样才能在内部使用这样的条件$sum
来获得适当的结果?
@Ashh 要求的示例消息文档:
{
"_id" : ObjectId("5ef0796fdb424a92c4200cdd"),
"read" : [
ObjectId("5ef078df7ce82f2e5cf3b586")
],
"content" : "Test message",
"sender" : ObjectId("5ef078df7ce82f2e5cf3b586"),
"room" : ObjectId("5ed4ffcdd13f45b4104a1669"),
"createdAt" : ISODate("2020-06-22T09:27:11.017Z"),
"updatedAt" : ISODate("2020-06-22T09:27:11.017Z")
}
还有一个样板间文件:
{
"_id" : ObjectId("5ed4ffcdd13f45b4104a1669"),
"participants" : [
ObjectId("5ed4ffbcd13f45b4104a1667"),
ObjectId("5ef078df7ce82f2e5cf3b586")
],
"pending" : [],
"name" : "Global",
"type" : "CHANNEL",
"creator" : ObjectId("5ed4ffbcd13f45b4104a1667"),
"createdAt" : ISODate("2020-06-01T13:17:01.935Z"),
"updatedAt" : ISODate("2020-06-01T13:17:01.935Z")
}
解决方案
$nin
不是聚合运算符,但是$in
是,您可以使用反转逻辑$in
$cond有两种语法
{ $cond: { if: <boolean-expression>, then: <true-case>, else: <false-case> } }
和
{ $cond: [ <boolean-expression>, <true-case>, <false-case> ] }
我们需要用 0 替换真案例,用 1 替换假案例,因为我们将计算不在数组中的案例
$sum: {
$cond: [
{ $in: [request.currentUser._id, "$messages.read"] },
0, // add 0 if in array
1 // add 1 if not in array
]
}
如果messages.read
不存在,则会导致错误,因此您最好将其包装为$ifNull
$sum: {
$cond: [
{ $in: [request.currentUser._id, { $ifNull:[ "$messages.read", []] }] },
0, // add 0 if in array
1 // add 1 if not in array
]
}
推荐阅读
- javascript - 在JS中按值对嵌套字典进行排序
- python - Django:子目录中的应用程序相对导入
- c++ - 使用非虚基类函数与派生类非实现虚函数之间的区别
- docker-compose - 是否可以在 docker-compose 中使用“--cache-from”之类的东西?
- c - C - 如何为哈希图中的同一个键分配多个值?
- angular - 如何将默认打开页面更改为 AppComponent 以外的组件?
- python - Python 项目的 Docker 运行失败
- spring - Spring Batch REST服务的中间结果存储
- excel - 使用超过 10 天的数据生成折线图,但按小时而不是按天显示
- node.js - 在 Azure node.js 服务上安装 bip32 时生成错误