Database Ops · 6 of 6

aggregate

Run a full aggregation pipeline inside a procedure. Returns an array of documents.

Signature

aggregate(collection, [stage1, stage2, ...])

Sum

proc total_sales() {
    return aggregate("orders", [
        {$group: {_id: null, total: {$sum: "$amount"}}}
    ])
}

Group by category

proc sales_by_category() {
    return aggregate("orders", [
        {$group: {_id: "$category", total: {$sum: "$amount"}, n: {$sum: 1}}},
        {$sort: {total: -1}}
    ])
}

Filter then group

proc monthly_revenue(year, month) {
    return aggregate("orders", [
        {$match: {year: year, month: month, status: "paid"}},
        {$group: {_id: "$category", total: {$sum: "$amount"}}},
        {$sort: {total: -1}}
    ])
}

Top-N

proc top_customers(n) {
    return aggregate("orders", [
        {$group: {_id: "$customer_id", spend: {$sum: "$amount"}, orders: {$sum: 1}}},
        {$sort: {spend: -1}},
        {$limit: n}
    ])
}

Avg / min / max

proc product_stats(sku) {
    return aggregate("reviews", [
        {$match: {sku: sku}},
        {$group: {
            _id: "$sku",
            avg_rating: {$avg: "$rating"},
            min_rating: {$min: "$rating"},
            max_rating: {$max: "$rating"},
            count: {$sum: 1}
        }}
    ])
}

$lookup (join)

proc orders_with_customer() {
    return aggregate("orders", [
        {$lookup: {
            from: "customers", localField: "customer_id",
            foreignField: "_id", as: "customer"
        }},
        {$limit: 100}
    ])
}

$unwind + $group

proc tag_popularity() {
    return aggregate("posts", [
        {$unwind: "$tags"},
        {$group: {_id: "$tags", n: {$sum: 1}}},
        {$sort: {n: -1}},
        {$limit: 20}
    ])
}

Use the result

proc check_quota(user_id, monthly_limit) {
    let result = aggregate("messages", [
        {$match: {user_id: user_id, this_month: true}},
        {$group: {_id: null, total: {$sum: 1}}}
    ])
    let used = 0
    if result[0] != null {
        used = result[0].total
    }
    return {used: used, limit: monthly_limit, ok: used < monthly_limit}
}

For the full stage and operator reference, see Aggregation Pipeline.

Report Issue