mongodb - MongoDB 聚合查询 Null 字段
问题描述
在文件集合中,我的结构如下:
{
'number': '0001',
'name': 'user №',
'sessions': [
{
'created': ISODate('2020-01-01T00:00:00'),
'session_id': '7WGnQhFGgDgC2FDfGwbgEaLbPMMBofPFVrVh9Pn2quooAcgxZc',
'actions': [
{
'type': 'read',
'created': ISODate('2020-01-01T01:20:01'),
},
{
'type': 'read',
'created': ISODate('2020-01-01T01:21:13'),
},
{
'type': 'create',
'created': ISODate('2020-01-01T01:33:59'),
}
],
}
]
}
我需要编写一个聚合查询,以这种形式显示每个用户和每个动作类型的最后一个动作,以及它们的总和:
{
'number': '0001',
'actions': [
{
'type': 'create',
'last': 'created': ISODate('2020-01-01T01:33:59'),
'count': 1,
},
{
'type': 'read',
'last': 'created': ISODate('2020-01-01T01:21:13'),
'count': 2,
},
{
'type': 'update',
'last': null,
'count': 0,
},
{
'type': 'delete',
'last': null,
'count': 0,
},
]
}
所以,我已经写了一个请求,但是我不知道如何输出计数== 0的动作,以及如何正确格式化输出:
[{$unwind: "$sessions"},
{$unwind: { path: "$sessions.actions" }},
{$group: {"_id": {"number": "$number",
"type": "$sessions.actions.type"},
"created": {"$push": "$sessions.actions.created"},
"count": {"$sum": 1}}},
{$group: {"_id": {"number": "$_id.number"},
"actions": {"$push": {"type": "$_id.type",
"last": {"$max": "$created"},
"count": "$count"}}}}]
解决方案
如果您使用的是 mongodb 服务器 4.2 或更高版本,您可以使用 set https://mongoplayground.net/p/21XH75s-usE
db.collection.aggregate([
{
$unwind: "$sessions"
},
{
$unwind: {
path: "$sessions.actions"
}
},
{
$group: {
"_id": {
"number": "$number",
"type": "$sessions.actions.type"
},
"created": {
"$push": "$sessions.actions.created"
},
"count": {
"$sum": 1
}
}
},
{
$group: {
"_id": {
"number": "$_id.number"
},
"actions": {
"$push": {
"type": "$_id.type",
"last": {
"$max": "$created"
},
"count": "$count"
}
}
}
},
{
"$set": {
"actions": {
"$function": {
"body": "function(actions) {try { var act = ['read', 'create', 'delete', 'update']; act.forEach((entry) => { if (actions.filter(e => e.type === entry).length < 1) { actions.push({ 'count': 0, type: entry, last: null }); }}) }catch (e) { } return actions}",
"args": [
"$actions"
],
"lang": "js"
}
}
}
}
])
在这里我们检查是否缺少任何动作如果缺少我们添加默认值
推荐阅读
- python - 将一年中特定时间段的数据更改为零
- c++ - 如何通过 MFC 应用程序检查具有此类 id 的行是否存在于 Access DB 中的 db 中
- angular - ASP.NET Core API 时间从 Angular post call 缩短了 6 小时
- mysql - 在 MySQL 中使用多个表模拟相交并加入
- java - 置换数组并将每个结果保存到 ArrayList
- android - android后台任务,如果我的应用程序被杀死
- selenium - 如何跳过基于 Selenium OS 运行测试的 TestNG 测试
- javascript - mochawesome 报告的名称未按预期保存(即使 cypress.json 中的“reportFilename”已更改)
- database - 同一 Oracle 11 行上的两个并发更新会导致死锁或更新失败吗?
- python - 仅当有 24 个连续 NAN 或更多时才填充 NAN 值