sql - 聚合查询以在 mongodb 中的单个查询中获取所有不同的条件
问题描述
我的 mongodb 集合中的一个文档如下:
{
"transaction_id": "e10cc8d64204394cd35329a88dc4ab8f",
"timestamp": "2021-05-11 17:47:50",
"client_id": "chae@aklas.kr",
"ip": "172.69.34.31",
"level": "OK",
"request": {
"method": "POST",
"status_code": 200,
"status_name": "Ok",
"url": "/ocr/driver"
},
"bytes": 297,
"message": "Status authenticated successfully"
},
{
"transaction_id": "e10cc8d64204394cd35329a88dc4ab8f",
"timestamp": "2021-05-11 17:47:50",
"client_id": "chae@kkk.kr",
"ip": "172.69.34.31",
"level": "OK",
"request": {
"method": "POST",
"status_code": 200,
"status_name": "Ok",
"url": "/status/driver"
},
"bytes": 297,
"message": "Status authenticated successfully"
}......
我可以使用以下查询按时间戳(每天)获取每个 request.url 的总数。
db.getCollection('collection').aggregate([
{
$match: {
client_id: { $regex : '^chae@'},
'request.url': { $regex : '^\/ocr'}}
},
{ '$group' :
{
'_id': { $substr: [ "$timestamp", 0, 10 ] },
count: { $sum: 1 }
}
},
{
'$sort':
{ 'count': -1}
}
])
然后我得到 request.url 的结果,其中包含 /^ocr/
_id | count
2021-10-01 | 10
2021-09-30 | 15
2021-09-29 | 11
....
好像没问题。但是,如果我想获得不同的 request.url,我必须发送另一个查询。我可以通过一个查询一次获得所有不同 request.url 的结果吗?
我想要的结果是这样的。
_id | count(ocr) | count(status) | count(something else)
2021-10-01 | 10 | 20 | 56
2021-09-30 | 15 | 26 | 28
2021-09-29 | 11 | 87 | 466
我什至不知道在mongodb中是否有可能?请给我提意见。谢谢。
解决方案
询问
- group 也接受表达式,所以我们可以计算 group 值
- 这里我们有 2 个组键
- 他们的电子邮件以 chae 开头,url 以 /ocr 开头的那些
- 那些他们的电子邮件以 chae 开头,url 以 /status 开头的人
- 我们分别总结这些
- 如果您添加更多案例,
$switch
您可以为许多不同的搜索执行此操作 - 如果您在编写查询时不知道这些情况,则需要
{"$switch" ...}
动态构建它,您可以使用循环来完成,它很容易做到,循环变量并创建它 - 如果您在这些字段上有索引,则可以
$match
在顶部添加一个,例如仅允许
(or (chae and /ocr) (chae and /status) ...)
还有一个$facet
解决方案(方面 = 每个字段 1 个聚合)
- 如果在 $match , $facet 或 $group 上使用 index 类似的性能(你做正则表达式匹配所以测试索引使用),但 $facet 更简单的查询
- 如果没有索引,
$facet
每个字段将进行 1 次集合扫描,所以$group
我认为
aggregate(
[{"$group":
{"_id":
{"reg":
{"$switch":
{"branches":
[{"case":
{"$and":
[{"$regexMatch": {"input": "$client_id", "regex": "^chae@"}},
{"$regexMatch": {"input": "$request.url", "regex": "^/ocr"}}]},
"then": "chae-ocr"},
{"case":
{"$and":
[{"$regexMatch": {"input": "$client_id", "regex": "^chae@"}},
{"$regexMatch":
{"input": "$request.url", "regex": "^/status"}}]},
"then": "chae-status"}],
"default": "other"}},
"time": {"$substrCP": ["$timestamp", 0, 10]}},
"count": {"$sum": 1}}},
{"$project": {"_id": "$_id.time", "count": 1, "searched": "$_id.reg"}}])
推荐阅读
- python - Python 在获取现有全局变量时遇到问题
- java - 未经检查的分配:“java.util.List”到“java.util.Collection ”
- nginx - 如何通过 nGinx 限制 IP 对站点的访问?
- python - 由 pyinstaller 生成的 exe 引发“权限被拒绝”错误
- reactjs - 我的 redux dispatch 语句有什么问题?
- python - _tkinter.TclError:屏幕距离错误“.!startpage”
- r - 在平行坐标图中离散地选择我想要的变量/列,并设置它以便这个图例也显示实际值
- visual-studio - 使用内核和插件解决方案时的发布问题
- python-3.x - HackerRank 动态数组
- composer-php - “最小稳定性”键出现在包的 composer.json 中时有什么作用?