Mongodb 聚合管道模板
Mongodb 的 aggregate
在資料查詢、分析等操作中是一個強大的聚合操作,但我發現在嘗試編寫它時,即使是非常簡單的語法,也總是需要參考官方文件或 ChatGPT 或 Perplexity 等 AI 工具,因此我總結了一些常用的模式作為模板,以便在工作中快速參考。
模板
- 包含匹配、分組和欄位輸出階段的基本聚合管道
db.collection.aggregate(
[
{
$match: {}
},
{
$group: {}
},
{
$project: {}
}
]
)
- 按不同資料類型配對結果
db.collection.aggregate(
[
{
$match: {
name: 'andy', // string literal
count: 30, // number literal
is_login: true, // false, null
name: {
$in: ['andy', 'jiang'] // array contain
},
is_login: {
$not: { // opposite value
$in: [false, null]
}
},
count: {
$gte: 5 // $lte, $gt, $lt, $eq, $ne, etc
},
opened_at: {
$lt: new Date('2025-02-13') // $lte, $gt, $lt, $eq, $ne, etc
},
$or: [ // or, must be used at top level
{ x: { $lt: 0 } },
{ x: { $gt: 10 } }
],
$and: [ // and, must be used at top level
{ x: { $gt: 0 } },
{ x: { $lt: 10 } }
]
}
},
{
$group: {}
},
{
$project: {}
}
]
)
- 按
_id
分組計算值
db.collection.aggregate(
[
{
$match: {}
},
{
$group: {
_id: null, // group by all documents
_id: '$field', // group by single field
_id: { // group by multiple fields
field1: '$field1',
field2: '$field2'
},
total: {
$count: {}, // count doc way 1
$sum: 1 // count doc way 2
},
sum_of_x: {
$sum: '$x' // sum of x
},
avg_of_x: {
$avg: '$x' // avg of x
}
}
},
{
$project: {}
}
]
)
- 輸出特定欄位
db.collection.aggregate(
[
{
$match: {}
},
{
$group: {}
},
{
$project: {
_id: 0, // or false, do not output _id
field1: 1, // or true, output field1
field: '$_id', // output field used in single-field _id
x: '$_id.x', // output _id.x in multiple-field _id
y: '$arr.0', // output array element by index
z: '$obj.z', // output child object field
'x.y.z': 1 // output nested field
}
}
]
)
- 在匹配前使用
window
函數去重
db.collection.aggregate(
[
{
$setWindowFields: {
partitionBy: {
field1: '$field1',
field2: '$field2'
},
sortBy: {
_id: 1
},
output: {
rn: {
$documentNumber: {}
}
}
}
},
{
$match: {
rn: 1 // only keep records with row number = 1
}
},
{
$group: {}
},
{
$project: {}
}
]
)
- 使用
$dateTrunc
轉換時間戳
db.collection.aggregate(
[
{
$match: {}
},
{
$group: {
_id: {
field1: '$field1',
date_field: {
$dateTrunc: {
date: '$timestamp',
unit: 'day', // day, week, month
timezone: 'Asia/Tokyo',
startOfWeek: 'Monday'
}
}
},
field2: {
$sum: '$field2'
}
}
},
{
$project: {}
}
]
)
- 在按條件筛选過的結果中查找目標
db.collection.aggregate(
[
{ $match: { _id: { $gt: ObjectId('xxx') } } },
{ $sort: { _id: 1 } },
{ $limit: 1_000_000 },
{ $sort: { _id: -1 } },
{ $limit: 1 },
{ $project: { _id: 1 } }
]
)
參考文獻