集計
Overview
このガイドでは、Rust ドライバーで集計操作を実行する方法を学習できます。
Aggregation operations process data in your MongoDB collections based on specifications you can set in an aggregation pipeline. 集計パイプラインは、1 つ以上のステージで構成されます。 各ステージでは、式演算子に基づいて演算を実行します。 ドライバーが集計パイプラインを実行すると、集計結果が返されます。
このガイドには、次のセクションが含まれています。
「 集計操作と検索操作の比較 」では、集計操作と検索操作の機能の違いについて説明します。
サーバー制限では、集計操作のメモリ使用量に関するサーバーの制限について説明しています。
例では、さまざまなユースケースでの集計の例えを示します
追加情報では、このガイドで言及されている型とメソッドのリソースとAPIドキュメントへのリンクを提供します
アナロジー
集計操作は、組み立てラインを持つ自動車工場と同様に機能します。 組立ラインには、特定のタスクを実行するための専用ツールを備えたステーションがあります。 たとえば、自動車をビルドする場合、組立ラインは フレームから始まります。 その後、自動車フレームが組み立てラインを通過するにつれて、各ステーションは個別の部分を組み立てます。 その結果は変換された最終製品、完成品です。
組立ラインは集計パイプラインを表し、個々のステーションは集計ステージを表し、専用ツールは式演算子を表し、完成品は集計結果を表します。
集計操作と検索操作の比較
次の表は、集計操作で実行できる操作と比較して、検索操作で実行できるさまざまなタスクを示しています。 集計フレームワークは、データを変換および操作するための拡張機能を提供します。
検索操作 | 集計操作 |
---|---|
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 |
サーバーの制限
集計操作を実行するときは、次の制限を考慮してください。
返されるドキュメントは、 16メガバイトのBSON ドキュメント サイズ 制限に違反していない必要があります。
パイプライン ステージには、デフォルトで 100 メガバイトのメモリ制限があります。必要な場合は、 の allow_disk_use フィールドを設定することで、この制限を超えることができます。
AggregateOptions
$graphLookup演算子は、 100メガバイトの厳格なメモリ制限があり、
allow_disk_use
設定を無視します。
例
このセクションの例では、次のサンプル ドキュメントを使用します。 各ドキュメントは、書籍レビュー ウェブサイトのユーザー プロファイルを表し、名前、年数、ジャンル、およびウェブサイトで最後にアクティブになった日付に関する情報が含まれています。
{ "name": "Sonya Mehta", "age": 23, "genre_interests": ["fiction", "mystery", "memoir"], "last_active": { "$date": "2023-05-13T00:00:00.000Z" } }, { "name": "Selena Sun", "age": 45, "genre_interests": ["fiction", "literary", "theory"], "last_active": { "$date": "2023-05-25T00:00:00.000Z" } }, { "name": "Carter Johnson", "age": 56, "genre_interests": ["literary", "self help"], "last_active": { "$date": "2023-05-31T00:00:00.000Z" } }, { "name": "Rick Cortes", "age": 18, "genre_interests": ["sci-fi", "fantasy", "memoir"], "last_active": { "$date": "2023-07-01T00:00:00.000Z" } }, { "name": "Belinda James", "age": 76, "genre_interests": ["literary", "nonfiction"], "last_active": { "$date": "2023-06-11T00:00:00.000Z" } }, { "name": "Corey Saltz", "age": 29, "genre_interests": ["fiction", "sports", "memoir"], "last_active": { "$date": "2023-01-23T00:00:00.000Z" } }, { "name": "John Soo", "age": 16, "genre_interests": ["fiction", "sports"], "last_active": { "$date": "2023-01-03T00:00:00.000Z" } }, { "name": "Lisa Ray", "age": 39, "genre_interests": ["poetry", "art", "memoir"], "last_active": { "$date": "2023-05-30T00:00:00.000Z" } }, { "name": "Kiran Murray", "age": 20, "genre_interests": ["mystery", "fantasy", "memoir"], "last_active": { "$date": "2023-01-30T00:00:00.000Z" } }, { "name": "Beth Carson", "age": 31, "genre_interests": ["mystery", "nonfiction"], "last_active": { "$date": "2023-08-04T00:00:00.000Z" } }, { "name": "Thalia Dorn", "age": 21, "genre_interests": ["theory", "literary", "fiction"], "last_active": { "$date": "2023-08-19T00:00:00.000Z" } }, { "name": "Arthur Ray", "age": 66, "genre_interests": ["sci-fi", "fantasy", "fiction"], "last_active": { "$date": "2023-11-27T00:00:00.000Z" } }
ジャンル別年数インサイト
次の例では、各ジャンルに参加するユーザーの平均年数、最小値、最大値を計算します。
集計パイプラインには、次のステージが含まれています。
genre_interests
フィールドの各配列エントリを新しいドキュメントに分割する$unwind
ステージ。genre_interests
フィールドの値でドキュメントをグループ化する$group
ステージ。 このステージでは、$avg
、$min
、$max
演算子を使用して、平均、最小、最大のユーザー年数を検索します。
let age_pipeline = vec![ doc! { "$unwind": doc! { "path": "$genre_interests" } }, doc! { "$group": doc! { "_id": "$genre_interests", "avg_age": doc! { "$avg": "$age" }, "min_age": doc! { "$min": "$age" }, "max_age": doc! { "$max": "$age" } } } ]; let mut results = my_coll.aggregate(age_pipeline).await?; while let Some(result) = results.try_next().await? { println!("* {:?}", result); }
* { "_id": "memoir", "avg_age": 25.8, "min_age": 18, "max_age": 39 } * { "_id": "sci-fi", "avg_age": 42, "min_age": 18, "max_age": 66 } * { "_id": "fiction", "avg_age": 33.333333333333336, "min_age": 16, "max_age": 66 } * { "_id": "nonfiction", "avg_age": 53.5, "min_age": 31, "max_age": 76 } * { "_id": "self help", "avg_age": 56, "min_age": 56, "max_age": 56 } * { "_id": "poetry", "avg_age": 39, "min_age": 39, "max_age": 39 } * { "_id": "literary", "avg_age": 49.5, "min_age": 21, "max_age": 76 } * { "_id": "fantasy", "avg_age": 34.666666666666664, "min_age": 18, "max_age": 66 } * { "_id": "mystery", "avg_age": 24.666666666666668, "min_age": 20, "max_age": 31 } * { "_id": "theory", "avg_age": 33, "min_age": 21, "max_age": 45 } * { "_id": "art", "avg_age": 39, "min_age": 39, "max_age": 39 } * { "_id": "sports", "avg_age": 22.5, "min_age": 16, "max_age": 29 }
時間コンポーネントでグループ化
次の例では、各月に最後にアクティブだったユーザーの数を調べます。
集計パイプラインには、次のステージが含まれています。
$project
ステージを使用して、last_active
フィールドから月を数値としてmonth_last_active
フィールドに抽出します$group
ステージ: ドキュメントをmonth_last_active
フィールドでグループ化し、各月のドキュメント数をカウント$sort
ステージ: で昇順の並べ替えを設定します
let last_active_pipeline = vec![ doc! { "$project": { "month_last_active" : doc! { "$month" : "$last_active" } } }, doc! { "$group": doc! { "_id" : doc! {"month_last_active": "$month_last_active"} , "number" : doc! { "$sum" : 1 } } }, doc! { "$sort": { "_id.month_last_active" : 1 } } ]; let mut results = my_coll.aggregate(last_active_pipeline).await?; while let Some(result) = results.try_next().await? { println!("* {:?}", result); }
* { "_id": { "month_last_active": 1 }, "number": 3 } * { "_id": { "month_last_active": 5 }, "number": 4 } * { "_id": { "month_last_active": 6 }, "number": 1 } * { "_id": { "month_last_active": 7 }, "number": 1 } * { "_id": { "month_last_active": 8 }, "number": 2 } * { "_id": { "month_last_active": 11 }, "number": 1 }
一般的なジャンルを計算する
次の例では、ユーザーの興味に表示される頻度に基づいて、最も一般的な 3 つのジャンルを検索します。
集計パイプラインには、次のステージが含まれています。
$unwind
ステージ:genre_interests
フィールドの各配列エントリを新しいドキュメントに分割$group
ステージ: ドキュメントをgenre_interests
フィールドでグループ化し、各ジャンルのドキュメント数をカウントします$sort
ステージ: ステージ: 降順の並べ替えを設定する$limit
最初の 3 つのジャンルのみを表示するステージ
let popularity_pipeline = vec![ doc! { "$unwind" : "$genre_interests" }, doc! { "$group" : doc! { "_id" : "$genre_interests" , "number" : doc! { "$sum" : 1 } } }, doc! { "$sort" : doc! { "number" : -1 } }, doc! { "$limit": 3 } ]; let mut results = my_coll.aggregate(popularity_pipeline).await?; while let Some(result) = results.try_next().await? { println!("* {:?}", result); }
* { "_id": "fiction", "number": 6 } * { "_id": "memoir", "number": 5 } * { "_id": "literary", "number": 4 }
詳細情報
このガイドで言及されている概念の詳細については、次のサーバー マニュアル エントリを参照してください。
aggregate()
メソッドの動作の詳細については、「データ取得 ガイドの集計操作セクションを参照してください。
集計パイプライン内での結果の並べ替えの詳細については、「 結果の並べ替え 」ガイドを参照してください。
API ドキュメント
このガイドで言及されているメソッドとタイプの詳細については、次のAPIドキュメントを参照してください。