mongodb - 当一个数组元素出现在另一个元素之前时匹配(MongoDb)
问题描述
我收藏中的文件我的订单结构如下:
[
{
OrderId: 'ID1',
StatusLog: [
{
Timestamp: 'Some ISO Date',
Status: 1,
Reason: 'Because',
User: 'User1'
},
{
Timestamp: 'Some ISO Date',
Status: 2,
Reason: 'No Idea',
User: 'User2'
},
{
Timestamp: 'Some ISO Date',
Status: 3,
Reason: 'Because',
User: 'User2'
},
{
Timestamp: 'Some ISO Date',
Status: 2 // NOTE: status can go back to 2,
Reason: 'Some Idea',
User: 'User1'
}
},
{
OrderId: 'ID2',
StatusLog: [
{
Timestamp: 'Some ISO Date',
Status: 1,
Reason: 'Because',
User: 'User1'
},
{
Timestamp: 'Some ISO Date',
Status: 2,
Reason: 'The reason to include in results',
User: 'User2'
},
{
Timestamp: 'Some ISO Date',
Status: 3,
Reason: 'Because',
User: 'User2'
}
}
]
我编写了一个聚合查询,可以让我计算每个原因+用户组合的订单数量。
[
{
$unwind: {
path: '$StatusLog'
}
},
{
$match: {
'StatusLog.Status': 2
}
},
{
$group: {
_id: {
'reason': '$StatusLog.Reason',
'user': '$StatusLog.User'
},
'orderCount': { $sum: 1 }
}
},
]
上述查询的输出是我需要的确切格式。但是,我希望将这些过滤器添加到查询中:
- 订单必须包含 StatusLog 元素,Status=2
- 订单必须包含之前的StatusLog 元素,Status=3
- 每个订单只能计算一次
因此,从上面的示例数据数组中,只有 OrderId='ID1' 的订单,结果应该是:
[
{
"_id" : {
"reason" : "The reason to include in results",
"user" : "User2"
},
"orderCount" : 1.0
}
]
任何帮助,将不胜感激。
解决方案
$unwind
解构StatusLog
数组$match
2 或 3 中的状态$group
按用户并制作数组Status
,获取第一个原因并orderCount
获取Status
2$match
使用过滤器在 2 和 3 中具有状态的用户$all
db.collection.aggregate([
{ $unwind: "$StatusLog" },
{ $match: { "StatusLog.Status": { $in: [2, 3] } } },
{
$group: {
_id: "$StatusLog.User",
Status: { $push: "$StatusLog.Status" },
Reason: { $first: "$StatusLog.Reason" },
orderCount: {
$sum: { $cond: [{ $eq: ["$StatusLog.Status", 2] }, 1, 0] }
}
}
},
{ $match: { Status: { $all: [2, 3] } } }
])
推荐阅读
- r - 使用 plyr (d_ply) 和 ggplot2 选择的错误未定义列
- jquery - 如何将值与空气日期时间选择器 Jquery 插件与模型绑定?
- django - 为什么我在 Django 博客中收到 pylint 错误?如何解决这个问题?安装了pylint。使用 VSC Mac
- javascript - 谷歌标签管理器自定义 javascript 变量增量
- visual-studio-code - 如何在 Visual Studio Code 中关闭(或折叠)活动文件菜单栏?
- cakephp - 将输入中的数据保存在表中
- angular - 字符串插值角内的转义字符
- ruby - Jekyll 中的运行时依赖与开发依赖
- javascript - 在工作线程nodejs中调用函数
- azure - 使用 Azure Devops 将控制台应用程序部署到 Azure VM 上的文件系统