mongodbのaggregateがパワフルで便利

  • 投稿日:
  • by

mongodbはドキュメントベースのデータベースですが、APIがシンプルでよいです。これまで、find()count()で足りていたのですが、ちょっと複雑なことをやろうとするとクライアント側で処理するはめになってしまいました。

mongodbの集計機能にはいくつかの種類があります。

http://docs.mongodb.org/manual/core/aggregation/

によると、Aggregation Pipeline, Map-Reduce, Single Purpose Aggregation Operationsとあります。 最後のSingle Purpose Aggregation Operationsはまさにcount()のようなものなのですが、他にもdistinct()group()もあります。SQLから類推すれば機能は分かりやすいでしょう。 Map-Reduceは並列処理にはいいでしょう。ただ、JavaScriptの関数を記述することになります。なんでもできるといえばなんでもできるのですが。 残るは、Aggregation Pipelineです。これは処理を逐次的に書くので分かりやすいのが利点ですが、注目したのはJSONで記述できることです。JavaScriptの関数と違ってシリアライズができるのがうれしい。Pipeline Operatorsというのがあって、そこそこ柔軟に書けます。

今回は詳しく述べませんが、参考までにパイプラインのサンプルを載せておきます。

var pipeline = [{
  $project: {
    record: '$records'
  }
}, {
  $unwind: '$record'
}, {
  $match: {
    'record.name': target_name
  }
}, {
  $group: {
    _id: 'all',
    count: {
      $sum: '$record.score'
    }
  }
}];

この$unwindがいいですね。ドキュメントを展開してくれるのです。

欲を言えば、パイプラインではなく、処理を分岐できる有効グラフを記述できたらさらに強力だったろうに。

さて、なぜJSONで記述したかったかというと、social-cms-backendで使いたかったからです。aggregateをサポートしてバージョンアップしました。

https://www.npmjs.org/package/social-cms-backend