MongoDB如何用单条聚合查询统计不同request.url的每日请求量
MongoDB单查询统计多URL规则每日请求量方案
该需求完全可以在MongoDB中实现,根据你是否提前明确需要统计的URL匹配规则,可选择以下两种实现方式:
方案一:规则固定场景直接生成宽表(推荐)
如果你提前知道所有需要统计的URL前缀规则,直接在$group阶段通过$cond条件判断累加计数即可,输出结果和你预期的格式完全一致。
聚合查询语句如下:
db.getCollection('collection').aggregate([ { $match: { client_id: { $regex : '^chae@'} // 移除原URL过滤规则,保留客户端过滤即可统计所有符合要求的请求 } }, { $group: { '_id': { $substr: [ "$timestamp", 0, 10 ] }, // 统计ocr前缀请求量 'count(ocr)': { $sum: { $cond: [ { $regexMatch: { input: "$request.url", regex: /^\/ocr/ } }, 1, 0 ] } }, // 统计status前缀请求量 'count(status)': { $sum: { $cond: [ { $regexMatch: { input: "$request.url", regex: /^\/status/ } }, 1, 0 ] } }, // 按需添加其他规则的统计项即可 'count(something else)': { $sum: { $cond: [ { $regexMatch: { input: "$request.url", regex: /^\/xxx/ } }, 1, 0 ] } } } }, { $sort: { '_id': -1 } // 按日期倒序排列 } ])
说明:
- 每个统计字段用
$cond判断当前请求的URL是否匹配对应规则,匹配则计数+1,否则+0 - 输出字段可以根据你的业务需求自由增减,执行后直接得到你预期的宽表格式结果
方案二:规则不固定场景全量统计
如果你不确定需要统计的URL前缀有哪些,想要一次性统计所有出现过的URL前缀的每日数据,可以先按日期+URL前缀分组统计,再聚合为同日期的统计集合:
db.getCollection('collection').aggregate([ { $match: { client_id: { $regex : '^chae@'} } }, // 提取URL前缀,示例取第一个斜杠和第二个斜杠之间的内容作为前缀标识 { $addFields: { urlPrefix: { $arrayElemAt: [ { $split: [ "$request.url", "/" ] }, 1 ] } } }, // 按日期+URL前缀分组统计 { $group: { _id: { date: { $substr: [ "$timestamp", 0, 10 ] }, prefix: "$urlPrefix" }, count: { $sum: 1 } } }, // 按日期聚合,把同日期的所有前缀统计合并 { $group: { _id: "$_id.date", urlStats: { $push: { k: { $concat: [ "count(", "$_id.prefix", ")" ] }, v: "$count" } } } }, // 把数组转为对象字段 { $replaceRoot: { newRoot: { $mergeObjects: [ { _id: "$_id" }, { $arrayToObject: "$urlStats" } ] } } }, { $sort: { '_id': -1 } } ])
说明:
- 该方案会自动识别所有请求中的URL前缀,无需提前定义规则
- 输出结果中每个日期文档会自动生成对应前缀的计数字段,适合前缀不固定的场景使用
- 该方案要求MongoDB版本≥3.4.4(支持
$arrayToObject和$replaceRoot操作符)
内容的提问来源于stack exchange,提问作者user1942626
相关产品推荐
相关产品推荐

