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" } } }, // 2番目のステージ、グルーピングと集計
{ $sort: { total: -1 } } // 3番目のステージ、結果をソート
]
同等の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に接続しコレクションオブジェクトを取得するコードはここに省略されています。クイックスタートチュートリアルを参照してください。
// Golangのデータ構造を使用してMongoDBのネイティブ構文を表現した、統計解析式。
// 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型(マップ構造の一種)を使用してクエリ結果を格納する
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"])
}
}
Tip: より多くのMongoDBの集計構文については、MongoDB アグリゲーション パイプラインを参照してください。