[MongoDB] unique な値を算出する distinct, aggregate

MongoDB で unique な値を distinct, aggregate を使って算出するサンプルコードをご紹介します。

MongoDB | モンゴディービー

MongoDB で unique な値を算出するサンプルコード

distinct で unique user を算出する

db.collection.distinct(‘field’) を使うだけで OK です。

以下は、オーダーのユニークユーザーを取得しているサンプルクエリです。

var users = db.orders.distinct('user');

複雑な条件ではければ distinct を使うだけでいいですが、document 数が多いとエラーが出ることもあります。

exception: distinct too big, 16mb cap

orders document が大量に存在して 16MB の制限を超えてしまう場合、以下のようなエラーが発生してしまいます。この場合、次に紹介する aggregate で集計しましょう。

> var users = db.orders.distinct('user');
2019-06-22T12:52:05.819+0000 E QUERY    Error: distinct failed: {
	"errmsg" : "exception: distinct too big, 16mb cap",
	"code" : 17217,
	"ok" : 0
}
    at Error ()
    at DBCollection.distinct (src/mongo/shell/collection.js:1237:15)
    at (shell):1:19 at src/mongo/shell/collection.js:1237

aggregate で unique user を算出する

aggregate を使えば exception: distinct too big, 16mb cap エラーは発生しませんが .forEach() .push() の実行時間がそれなりに掛かってしまいます。

var users = [];
db.orders.aggregate(
  [
    {
      $group: { _id: '$user' }
    }
  ]
).forEach(function(result) {
  users.push(result._id);
});

以上、MongoDB クエリで unique な値を集計したい、現場からお送りしました。