SQL GROUP BYとCOUNTをMongoDBの$groupと$sumに変換する

SQL GROUP BYとCOUNT(*)が$groupと$sumアキュムレータを使用したMongoDB集計パイプラインに変換され、ドキュメントをカウントする方法を学びます。

Aggregation

詳細な説明

GROUP BY COUNTから$group $sumへ

SQLのGROUP BYCOUNT(*)は行をグループ化し、グループごとの出現数をカウントします。MongoDBでは、$groupステージを持つaggregate()パイプラインが必要です。

SQLの例

SELECT status, COUNT(*) AS total
FROM orders
GROUP BY status

生成されるMongoDBクエリ

db.orders.aggregate([
  {
    $group: {
      _id: "$status",
      total: { $sum: 1 },
      status: { $first: "$status" }
    }
  }
])

$groupの仕組み

$groupステージはSQL GROUP BYのMongoDBの同等物です。_idフィールドはグループ化の基準を指定します(ドキュメントフィールドを参照するために$プレフィックス付き)。$sum$avg$min$maxなどのアキュムレータ演算子が各グループの値を計算します。

COUNT(*) vs COUNT(column)

  • COUNT(*)は全行をカウント、{ $sum: 1 }に変換 — グループ内の各ドキュメントに1を加算
  • COUNT(column)は非NULL値をカウント、MongoDBではまずnull値をフィルタリングする$matchステージが必要、その後{ $sum: 1 }

ソートの追加

ORDER BY total DESCを再現するには、$groupの後に$sortステージを追加します:

db.orders.aggregate([
  { $group: { _id: "$status", total: { $sum: 1 } } },
  { $sort: { total: -1 } }
])

HAVING句

SQLのHAVINGは集計後にグループをフィルタリングします。MongoDBでは、$groupステージの後に配置される$matchステージです:

SELECT status, COUNT(*) AS total FROM orders GROUP BY status HAVING COUNT(*) > 10
db.orders.aggregate([
  { $group: { _id: "$status", total: { $sum: 1 } } },
  { $match: { total: { $gt: 10 } } }
])

ユースケース

ステータス別の注文数、国別のユーザー数、タイプ別のイベント数を表示する分析ダッシュボードは基本的なレポーティングクエリです。GROUP BY COUNTパターンは、SQLからMongoDBへの移行で最も頻繁に変換される集計クエリと言えます。

試してみる — SQL to MongoDB Query

フルツールを開く