Docs Menu

集計によるデータの変換

このガイドでは、Mongoid を使用して集計操作 を実行する方法を学習できます。

集計操作により MongoDB コレクション内のデータが処理され、計算結果が返されます。 クエリ API の一部である MongoDB 集計フレームワークは、データ処理パイプラインの概念をモデル化したものです。 ドキュメントは 1 つ以上の ステージを含むパイプラインに投入され、そこで集計結果に変換されます。

集計操作は、組み立てラインを持つ自動車工場と同様に機能します。 組立ラインには、特定のタスクを実行するための専用ツールを備えたステーションがあります。 たとえば、自動車をビルドする場合、組立ラインは フレームから始まります。 その後、自動車フレームが組み立てラインを通過するにつれて、各ステーションは個別の部分を組み立てます。 その結果は変換された最終製品、完成品です。

組立ラインは集計パイプラインを表し、個々のステーションは集計ステージを表し、専用ツールは式演算子を表し、完成品は集計結果を表します。

次の表は、集計操作で実行できる操作と比較して、検索操作で実行できるさまざまなタスクを示しています。 集計フレームワークは、データを変換および操作するための拡張機能を提供します。

検索操作
集計操作
Select certain documents to return
Select which fields to return
Sort the results
Limit the results
Count the results
Select certain documents to return
Select which fields to return
Sort the results
Limit the results
Count the results
Rename fields
Compute new fields
Summarize data
Connect and merge data sets

Mongoid の高レベルのドメイン固有言語(DSL)を使用して、集計パイプラインを構築できます。 DSL は次の集計パイプライン演算子をサポートしています。

演算子
メソッド名

group

project

unwind

前述の演算子のいずれかを使用して集計パイプラインを作成するには、Criteria のインスタンスで対応するメソッドを呼び出します。 メソッドを呼び出すと、Criteriaインスタンスの pipeline アトリビューションに集計操作が追加されます。 集計パイプラインを実行するには、pipeline 属性の値を Collection#aggregate メソッドに渡します。

次の クラスによってモデル化されたドキュメントを含むコレクションを含むデータベースを考えてみましょう。

class Tour
include Mongoid::Document
embeds_many :participants
field :name, type: String
field :states, type: Array
end
class Participant
include Mongoid::Document
embedded_in :tour
field :name, type: String
end

この例では、Tour モデルはツアーの名前とそのパスを移動する州を表し、Participant モデルはツアーに参加している人の名前を表します。

次の例では、次の集計操作を使用して、参加者が訪問した州を出力する集計パイプラインを作成します。

  • match: participants.nameフィールド値が "Serenity" であるドキュメントを検索

  • unwind は、states 配列フィールドを分解し、 配列内の各要素のドキュメントを出力します

  • group は、ドキュメントを statesフィールドの値でグループ化します

  • project は、パイプラインに_id フィールドと states フィールドのみを返すように要求します。

criteria = Tour.where('participant.name' => 'Serenity').
unwind(:states).
group(_id: 'states', :states.add_to_set => '$states').
project(_id: 0, states: 1)
@states = Tour.collection.aggregate(criteria.pipeline).to_json
[{"states":["OR","WA","CA"]}]

Collection#aggregate メソッドでは、集計操作の配列を渡すことで、対応するビルダ メソッドがない集計操作を実行できます。 このメソッドを使用して集計を実行すると、Mongoid::Document モデル インスタンスではなく、未加工の BSON::Document オブジェクトが返されます。

次の クラスによってモデル化されたドキュメントを含むコレクションを含むデータベースを考えてみましょう。

class Band
include Mongoid::Document
has_many :tours
has_many :awards
field :name, type: String
end
class Tour
include Mongoid::Document
belongs_to :band
field :year, type: Integer
end
class Award
include Mongoid::Document
belongs_to :band
field :name, type: String
end

次の例では、 2000 以降でツアーがあり、少なくとも 1 が付与されているすべてのバンドを検索するための集計パイプラインを作成します。

band_ids = Band.collection.aggregate([
{ '$lookup' => {
from: 'tours',
localField: '_id',
foreignField: 'band_id',
as: 'tours',
} },
{ '$lookup' => {
from: 'awards',
localField: '_id',
foreignField: 'band_id',
as: 'awards',
} },
{ '$match' => {
'tours.year' => {'$gte' => 2000},
'awards._id' => {'$exists' => true},
} },
{'$project' => {_id: 1}},
])
bands = Band.find(band_ids.to_a)
[
{"_id": "...", "name": "Deftones" },
{"_id": "...", "name": "Tool"},
...
]

Tip

上記の例では、出力ドキュメントの _idフィールドのみがプロジェクションされます。 次に、プロジェクションされた結果を使用してドキュメントが検索され、Mongoid::Document モデル インスタンスとして返されます。 このオプションの手順は、集計パイプライン を実行するために必要ではありません。

集計演算子の完全なリストを表示するには、「 集計演算子 」を参照してください。

集計パイプラインの組み立てと例については、「集計パイプライン 」を参照してください。

パイプライン ステージの作成の詳細については、「集計ステージ 」を参照してください。

このガイドで説明されているメソッドの詳細については、次の API ドキュメントを参照してください。