AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

集計によるデータの変換

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

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

Tip

完全な集計チュートリアル

サーバー マニュアルの「完全な集計パイプライン チュートリアル」のセクションには、一般的な集計タスクの詳細を説明するチュートリアルがあります。チュートリアルを選択し、ページの右上隅にある Select your language ドロップダウン メニューから Scala を選択します。

集計操作は自動車工場に似ています。工場内の組立ラインには、ドリルや溶接機のような、特定の作業をするための専用工具を備えた組立ステーションがあります。未加工のパーツが工場に搬入され、組立ラインで完成品に加工、組み立てられます。

集計パイプラインは組み立てライン、集計ステージは組み立てステーション、演算子式は専用ツールです。

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

検索操作
集計操作

返す特定のドキュメントを選択して返す
返すフィールドを選択して返す
結果を並べ替える
結果を制限する
結果をカウントする







返すドキュメントを選択する
返すフィールドを選択する 結果をソートする 結果を制限する 結果をカウントする フィールド名を変更する 新しいフィールドを計算する データを要約する
データセットを接続してマージする

集計操作を実行する際には、次の制限を考慮してください。

  • 返されたドキュメントは、 16メガバイトのBSONドキュメントサイズ制限に違反することはできません。

  • パイプライン ステージには、デフォルトで 100 メガバイトのメモリ制限があります。 この制限を超えるには、true の値を allowDiskUse() メソッドに渡し、そのメソッドを aggregate() にチェーンします。

  • $graphLookup 演算子には、 MB100 の厳格なメモリ制限があり、allowDiskUse() メソッドに渡される値を無視します。

注意

サンプル データ

このガイドの例では、Atlasサンプルデータセットsample_restaurantsデータベースにあるrestaurantsコレクションを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、Atlas を使い始める を参照してください。

集計 を実行するには、パイプラインステージを含むリストを aggregate() メソッドに渡します。 Scalaドライバーは、パイプラインステージを構築するためのヘルパーメソッドを含む Aggregatesクラスを提供します。

パイプラインステージとそれに対応する Aggregatesヘルパーメソッドの詳細については、次のリソースを参照してください。

このコード例では、ニューヨークの各地区のケーキの数のカウントを生成します。 そのためには、aggregate() メソッドを呼び出し、集計パイプラインをステージのリストとして渡します。 コードでは、次の Aggregatesヘルパーメソッドを使用してこれらのステージを構築します。

  • filter(): $match ステージを構築して、cuisine の値が であるドキュメントをフィルタリングします"Bakery"

  • group(): $group ステージを構築して、一致するドキュメントをborough フィールドでグループ化し、個別の 値ごとにドキュメントの数を蓄積します

val pipeline = Seq(Aggregates.filter(Filters.equal("cuisine", "Bakery")),
Aggregates.group("$borough", Accumulators.sum("count", 1))
)
collection.aggregate(pipeline)
.subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))
{"_id": "Brooklyn", "count": 173}
{"_id": "Queens", "count": 204}
{"_id": "Bronx", "count": 71}
{"_id": "Staten Island", "count": 20}
{"_id": "Missing", "count": 2}
{"_id": "Manhattan", "count": 221}

MongoDB が操作を実行する方法に関する情報を表示するには、 MongoDBクエリ プランナーにそれを説明するように指示できます。MongoDB が操作 を説明すると、実行プランとパフォーマンス統計が返されます。実行プランは、 MongoDB が操作を完了できる潜在的な方法です。 MongoDB に操作を説明するよう指示すると、 MongoDBが実行したプランと拒否された実行プランの両方がデフォルトで返されます。

集計操作 を説明するには、explain() メソッドを aggregate() メソッドに連鎖させます。 冗長レベルを explain() に渡すことで、メソッドが返す情報のタイプと量が変更されます。 冗長 の詳細については、 MongoDB Serverマニュアルの「 冗長モード 」を参照してください。

次の例では、 MongoDB に、前述の フィルター、グループ、ドキュメントの例の集計操作を説明するように指示します。このコードでは、ExplainVerbosity.EXECUTION_STATS の冗長値が explain() メソッドに渡されます。これにより、 メソッドは、当選プランの実行を説明する統計を返すように構成されます。

val pipelineToExplain = Seq(Aggregates.filter(Filters.equal("cuisine", "Bakery")),
Aggregates.group("$borough", Accumulators.sum("count", 1))
)
collection.aggregate(pipelineToExplain)
.explain(ExplainVerbosity.EXECUTION_STATS)
.subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))
{"explainVersion": "2", "queryPlanner": {"namespace": "sample_restaurants.restaurants",
"indexFilterSet": false, "parsedQuery": {"cuisine": {"$eq": "Bakery"}}, "queryHash": "865F14C3",
"planCacheKey": "0FC225DA", "optimizedPipeline": true, "maxIndexedOrSolutionsReached": false,
"maxIndexedAndSolutionsReached": false, "maxScansToExplodeReached": false, "winningPlan":
{"queryPlan": {"stage": "GROUP", "planNodeId": 3, "inputStage": {"stage": "COLLSCAN",
"planNodeId": 1, "filter": {"cuisine": {"$eq": "Bakery"}}, "direction": "forward"}},
...}

Tip

MongoDB 検索インデックスを持つコレクションでのみ使用可能

この集計パイプライン演算子は、MongoDB 検索インデックスを持つコレクションでのみ使用できます。

1 つ以上のフィールドの全文検索を指定するには、$searchパイプラインステージを作成します。 Scalaドライバーは、このステージを作成するための Aggregates.search()ヘルパーメソッドを提供します。 search() メソッドには次の引数が必要です。

  • SearchOperator インスタンス: 検索するフィールドとテキストを指定します。

  • SearchOptions インスタンス: 全文検索するオプションを指定します。使用するMongoDB検索インデックスの名前に index オプションを設定する必要があります。

この例では、次のアクションを実行するためのパイプラインステージを作成しています。

  • nameフィールドで"Salt" という単語を含むテキストを検索

  • 一致するドキュメントの _idname の値のみを予測

val operator = SearchOperator.text(SearchPath.fieldPath("name"), "Salt")
val options = searchOptions().index("<search index name>")
val pipeline = Seq(Aggregates.search(operator, options),
Aggregates.project(Projections.include("name")))
collection.aggregate(pipeline)
.subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))
{"_id": {"$oid": "..."}, "name": "Fresh Salt"}
{"_id": {"$oid": "..."}, "name": "Salt & Pepper"}
{"_id": {"$oid": "..."}, "name": "Salt + Charcoal"}
{"_id": {"$oid": "..."}, "name": "A Salt & Battery"}
{"_id": {"$oid": "..."}, "name": "Salt And Fat"}
{"_id": {"$oid": "..."}, "name": "Salt And Pepper Diner"}

重要

上記の例を実行するには、nameフィールドをカバーする restaurantsコレクションにMongoDB 検索インデックスを作成する必要があります。次に、"<search index name>" プレースホルダーをインデックスの名前に置き換えます。MongoDB 検索インデックスの詳細については、MongoDB 検索インデックスガイドを参照してください。

Scalaドライバーは次の演算子のヘルパーメソッドを提供します。

演算子
説明

不完全な入力 string からの文字シーケンスを含む単語またはフレーズを検索します。

2 つ以上の演算子を 1 つのクエリに結合します。

フィールドが指定した値と一致するかどうかを確認します。equals() メソッドと equalsNull() メソッドにマップされます。

指定されたインデックス付きフィールド名へのパスがドキュメント内に存在するかどうかをテストします。

指定されたパスにあるBSON番号、日付、ブール値、ObjectId、uuid、または string 値の配列を検索し、フィールドの値が指定された配列内の任意の値と等しいドキュメントを返します。

入力ドキュメントに類似するドキュメントを返します。

数値、日付、 GeoJSONポイント値のクエリとスコアリングをサポートします。

インデックス構成で指定されたアナライザを使用して、順序付けられたタームのシーケンスを含むドキュメントを検索します。

インデックス付きフィールドと値の組み合わせのクエリをサポートします。

数値、日付、string 値のクエリとスコアリングをサポートします。numberRange() メソッドと dateRange() メソッドにマップされます。

クエリフィールドを 正規式として解釈します。

インデックス構成で指定したアナライザを使用して全文検索を実行します。

検索stringに任意の文字と一致する特殊文字を使用するクエリを有効にします。

この例を実行する前に、moviesコレクションに次の定義を持つMongoDB検索インデックスを作成する必要があります。

{
"mappings": {
"dynamic": true,
"fields": {
"title": {
"analyzer": "lucene.keyword",
"type": "string"
},
"genres": {
"normalizer": "lowercase",
"type": "token"
}
}
}
}

MongoDB 検索インデックスの作成の詳細については、MongoDB 検索インデックス ガイドを参照してください。

次のコードでは、次の仕様を持つ $search ステージが作成されます。

  • genres 配列に "Comedy" が含まれていることを確認

  • fullplotフィールドでフレーズ "new york" を検索します

  • 1950 から 2000 までの year 値と一致します

  • "Love" というタームで始まる title 値を検索します

val searchStage = Aggregates.search(
SearchOperator.compound()
.must(
Iterable(
SearchOperator.in(fieldPath("genres"), List("Comedy")),
SearchOperator.phrase(fieldPath("fullplot"), "new york"),
SearchOperator.numberRange(fieldPath("year")).gtLt(1950, 2000),
SearchOperator.wildcard("Love *", fieldPath("title")),
).asJava
)
)
val projectStage = Aggregates.project(
Projections.include("title", "year", "genres"))
val aggregatePipelineStages = Seq(searchStage, projectStage)
collection.aggregate(aggregatePipelineStages)
.subscribe((doc: Document) => println(doc.toJson()),
(e: Throwable) => println(s"There was an error: $e"))
{"_id": ..., "genres": ["Comedy", "Romance"], "title": "Love at First Bite", "year": 1979}
{"_id": ..., "genres": ["Comedy", "Drama"], "title": "Love Affair", "year": 1994}

MongoDB 検索するヘルパーメソッドの詳細については、ドライバー Core API ドキュメントの SearchOperator インターフェース参照を参照してください。

このガイドで説明されているトピックについて詳しくは、 MongoDB Serverマニュアルの次のページ を参照してください。

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