集計
Overview
このガイドでは、MongoDB Kotlin ドライバーで集計操作を使用する方法を学習できます。
集計操作により MongoDB コレクション内のデータが処理され、計算結果が返されます。 クエリ API の一部である MongoDB の集計パイプラインは、データ処理パイプラインの概念をモデル化したものです。 ドキュメントは、ドキュメントを集計結果に変換するマルチステージのパイプラインに入力されます。
集計の別の方法は、自動車工場に似ています。 自動車工場内には組立ラインがあり、ドリルや溶接機のような、特定の作業をするための専用工具を備えた組立ステーションです。 未加工のパーツが工場に搬入され、完成品に加工、組み立てられます。
集計パイプラインは組み立てライン、集計ステージは組み立てステーション、演算子式は専用ツールです。
集計操作と検索操作の比較
find
操作を使用すると、次のことが可能になります。
何のドキュメントを返すかを選ぶ
返す項目フィールドの選択
結果を並べ替える
aggregation
操作を使用すると、次のことが可能になります。
すべての
find
操作を実行するフィールドの名前を変更する
フィールドを計算する
データを要約する
値をグループ化する
集計操作には、次のように留意する必要がある制限がいくつかあります。
返されるドキュメントは、 16メガバイトのBSON ドキュメント サイズ 制限に違反していない必要があります。
パイプライン ステージには、デフォルトで 100 メガバイトのメモリ制限があります。 必要な場合、 allowDiskUse メソッドを使用してこの制限を超えることができます。
参考文献
サンプルデータ
例では、MongoDB の次のデータのコレクションを使用します。
[ {"name": "Sun Bakery Trattoria", "contact": {"phone": "386-555-0189", "email": "SunBakeryTrattoria@example.org", "location": [-74.0056649, 40.7452371]}, "stars": 4, "categories": ["Pizza", "Pasta", "Italian", "Coffee", "Sandwiches"]}, {"name": "Blue Bagels Grill", "contact": {"phone": "786-555-0102", "email": "BlueBagelsGrill@example.com", "location": [-73.92506, 40.8275556]}, "stars": 3, "categories": ["Bagels", "Cookies", "Sandwiches"]}, {"name": "XYZ Bagels Restaurant", "contact": {"phone": "435-555-0190", "email": "XYZBagelsRestaurant@example.net", "location": [-74.0707363, 40.59321569999999]}, "stars": 4, "categories": ["Bagels", "Sandwiches", "Coffee"]}, {"name": "Hot Bakery Cafe", "contact": {"phone": "264-555-0171", "email": "HotBakeryCafe@example.net", "location": [-73.96485799999999, 40.761899]}, "stars": 4, "categories": ["Bakery", "Cafe", "Coffee", "Dessert"]}, {"name": "Green Feast Pizzeria", "contact": {"phone": "840-555-0102", "email": "GreenFeastPizzeria@example.com", "location": [-74.1220973, 40.6129407]}, "stars": 2, "categories": ["Pizza", "Italian"]}, {"name": "ZZZ Pasta Buffet", "contact": {"phone": "769-555-0152", "email": "ZZZPastaBuffet@example.com", "location": [-73.9446421, 40.7253944]}, "stars": 0, "categories": ["Pasta", "Italian", "Buffet", "Cafeteria"]}, {"name": "XYZ Coffee Bar", "contact": {"phone": "644-555-0193", "email": "XYZCoffeeBar@example.net", "location": [-74.0166091, 40.6284767]}, "stars": 5, "categories": ["Coffee", "Cafe", "Bakery", "Chocolates"]}, {"name": "456 Steak Restaurant", "contact": {"phone": "990-555-0165", "email": "456SteakRestaurant@example.com", "location": [-73.9365108, 40.8497077]}, "stars": 0, "categories": ["Steak", "Seafood"]}, {"name": "456 Cookies Shop", "contact": {"phone": "604-555-0149", "email": "456CookiesShop@example.org", "location": [-73.8850023, 40.7494272]}, "stars": 4, "categories": ["Bakery", "Cookies", "Cake", "Coffee"]}, {"name": "XYZ Steak Buffet", "contact": {"phone": "229-555-0197", "email": "XYZSteakBuffet@example.org", "location": [-73.9799932, 40.7660886]}, "stars": 3, "categories": ["Steak", "Salad", "Chinese"]} ]
コレクション内のデータは、次のRestaurant
データ クラスによってモデル化されます。
data class Restaurant( val name: String, val contact: Contact, val stars: Int, val categories: List<String> ) { data class Contact( val phone: String, val email: String, val location: List<Double> ) }
基本的な集計
集計を実行するには、集計ステージのリストを MongoCollection.aggregate()
メソッドに渡します。
Kotlin ドライバーは 集計 集計ステージのビルダを含むヘルパー クラス。
次の例で集計パイプラインは次のステージを使用しています。
$matchステージを使用して、
categories
配列フィールドに要素Bakery
を含むドキュメントをフィルタリングします。この例では、Aggregates.match
を使って$match
ステージを構築します。$groupステージを使用して、一致するドキュメントを
stars
フィールドでグループ化し、stars
の個別の値ごとにドキュメントの数を蓄積します。
data class Results( val id: Int, val count: Int) val resultsFlow = collection.aggregate<Results>( listOf( Aggregates.match(Filters.eq(Restaurant::categories.name, "Bakery")), Aggregates.group("\$${Restaurant::stars.name}", Accumulators.sum("count", 1)) ) ) resultsFlow.collect { println(it) }
Results(id=4, count=2) Results(id=5, count=1)
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。
集計の説明
MongoDB が操作を実行する方法に関する情報を表示するには、 AggregateFlow
クラスのexplain()
メソッドを使用します。 explain()
メソッドは実行プランとパフォーマンス統計を返します。 実行プランは、MongoDB が操作を完了できる潜在的な方法です。 explain()
メソッドは、当選プラン(MongoDB が実行されたプラン)と拒否されたプランの両方を提供します。
explain()
メソッドに冗長レベルを渡すことで、説明の詳細度を指定できます。
次のテーブルには、説明のすべての冗長レベルとそのユースケースが示されています。
冗長レベル | ユースケース |
---|---|
ALL_PLANS_EXECUTIONS | MongoDB でクエリを実行するのにどのプランを選んだらよいかを知りたい場合。 |
EXECUTION_STATS | クエリがうまく機能しているかどうかを知りたい場合。 |
QUERY_PLANNER | クエリに問題があり、問題を診断するためにできるだけ多くの情報が必要です。 |
次の例では、実行プランを生成する集計ステージの勝利プランの JSON 表現を出力します。
data class Results (val name: String, val count: Int) val explanation = collection.aggregate<Results>( listOf( Aggregates.match(Filters.eq(Restaurant::categories.name, "bakery")), Aggregates.group("\$${Restaurant::stars.name}", Accumulators.sum("count", 1)) ) ).explain(ExplainVerbosity.EXECUTION_STATS) // Prettyprint the output println(explanation.toJson(JsonWriterSettings.builder().indent(true).build()))
{ "explainVersion": "2", "queryPlanner": { // ... }, "command": { // ... }, // ... }
このセクションで述べられたトピックについて詳しくは、次のリソースを参照してください。
クエリプランサーバー マニュアル エントリ
ExplainVerbosity APIドキュメント
explain() APIドキュメント
AggregateFlow API ドキュメント
集計式
Kotlin ドライバーは、 $group
で使用するためのアキュムレータ式のビルダを提供します。 他のすべての式は、JSON 形式または互換性のあるドキュメント形式で宣言する必要があります。
Tip
次のいずれかの例の構文によって、 $arrayElemAt式が定義されます。
「カテゴリ」の前に$
が付いている場合、入力ドキュメントの「カテゴリ」フィールドを使用して、これがフィールド パスであることを MongoDB に伝えています。
Document("\$arrayElemAt", listOf("\$categories", 0)) // is equivalent to Document.parse("{ \$arrayElemAt: ['\$categories', 0] }")
次の例では、集計パイプラインは $project
ステージとさまざまな Projections
を使用して、name
フィールドと、値が categories
フィールドの最初の要素である計算フィールド firstCategory
を返します。
data class Results(val name: String, val firstCategory: String) val resultsFlow = collection.aggregate<Results>( listOf( Aggregates.project( Projections.fields( Projections.excludeId(), Projections.include("name"), Projections.computed( "firstCategory", Document("\$arrayElemAt", listOf("\$categories", 0)) ) ) ) ) ) resultsFlow.collect { println(it) }
Results(name=Sun Bakery Trattoria, firstCategory=Pizza) Results(name=Blue Bagels Grill, firstCategory=Bagels) Results(name=XYZ Bagels Restaurant, firstCategory=Bagels) Results(name=Hot Bakery Cafe, firstCategory=Bakery) Results(name=Green Feast Pizzeria, firstCategory=Pizza) Results(name=ZZZ Pasta Buffet, firstCategory=Pasta) Results(name=XYZ Coffee Bar, firstCategory=Coffee) Results(name=456 Steak Restaurant, firstCategory=Steak) Results(name=456 Cookies Shop, firstCategory=Bakery) Results(name=XYZ Steak Buffet, firstCategory=Steak)
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。