一架梯子,一头程序猿,仰望星空!
GoLang MongoDB教程 > 内容正文

Golang MongoDB 统计分析


类似SQL语句的Group by统计分析,MongoDB也支持,本章介绍Golang如果实现对MongoDB数据进行统计分析。

前置教程

请先阅读下面前置教程

测试数据

orders集合数据如下

{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }
{ _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }
{ _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }
{ _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }
{ _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }

分组统计

通过Collection.Aggregate函数执行统计查询。

下面是MongoDB一个统计分析的例子

[
    { $match: { status: "A" } },  // 第一个阶段, 根据查询条件匹配文档数据
    { $group: { _id: "$cust_id", total: { $sum: "$amount" } } },   // 第二个阶段,分组统计
    { $sort: { total: -1 } }  // 第三个阶段,对结果排序
]

等价SQL:

select sum(amount) as total from orders 
        where status="A" 
        group by cust_id 
        order by total desc

下面是Golang的写法

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    var coll *mongo.Collection

    // 这里忽略连接MongoDB、获取集合对象的代码,可以参考快速入门教程。

    // 统计分析表达式, 跟MongoDB原生语法是一样的,只是使用Golang 数据结构表示。
    // 不了解Golang mongoDB 数据模型,请阅读前面的章节。
    pipeline := mongo.Pipeline{
            {{"$match", bson.D{{"status", "A"}}}},
            {{"$group", bson.D{{"_id", "$cust_id"}, {"total", bson.D{{"$sum", "$amount"}}}}}},
            {{"$sort", bson.D{{"total", -1}}}}
    }

    // 设置超时时间
    opts := options.Aggregate().SetMaxTime(2 * time.Second)

    // 执行统计分析
    cursor, err := coll.Aggregate(
                                context.TODO(),  // 上下文参数
                                pipeline,  // 统计分析表达式
                                opts // 可选参数
                            )
    if err != nil {
        log.Fatal(err)
    }

    // 定义结果集合,这里使用bson.M类型(是一种map结构)存储查询结果
    var results []bson.M
    // 获取所有结果,保存至results变量
    if err = cursor.All(context.TODO(), &results); err != nil {
        log.Fatal(err)
    }

    // 遍历查询结果
    for _, result := range results {
        fmt.Printf("id =  %v , total =  %v \n", result["_id"], result["total"])
    }
}

提示:更多MongoDB统计分析语法,请参考MongoDB统计分析语法