Overview
このガイドでは、 Scalaドライバーを使用して集計操作 を実行する方法を学習できます。
集計操作により MongoDB コレクション内のデータが処理され、計算結果が返されます。 クエリ API の一部である MongoDB 集計フレームワークは、データ処理パイプラインの概念をモデル化したものです。 ドキュメントは 1 つ以上の ステージを含むパイプラインに投入され、そこで集計結果に変換されます。
Tip
完全な集計チュートリアル
サーバー マニュアルの「 完全な集計パイプライン チュートリアルScala Select your language」のセクションには、一般的な集計タスクの詳細を説明するチュートリアルがあります。チュートリアルを選択し、ページの右上隅にある ドロップダウン メニューから を選択します。
アナロジー
集計操作は自動車工場に似ています。工場内の組立ラインには、ドリルや溶接機のような、特定の作業をするための専用工具を備えた組立ステーションがあります。未加工のパーツが工場に搬入され、組立ラインで完成品に加工、組み立てられます。
集計パイプラインは組み立てライン、集計ステージは組み立てステーション、演算子式は専用ツールです。
集計操作と検索操作の比較
次の表は、検索操作が実行できるさまざまなタスクを示し、それらを集計操作と比較しています。 集計フレームワークは、データを変換および操作するための拡張機能を提供します。
検索操作 | 集計操作 |
|---|---|
返す特定のドキュメントを選択して返す |
|
制限
集計操作を実行する際には、次の制限を考慮してください。
返されたドキュメントは、 メガバイトのBSONドキュメントサイズ制限に違反することはできません。16
パイプライン ステージには、デフォルトで 100 メガバイトのメモリ制限があります。 この制限を超えるには、
trueの値をallowDiskUse()メソッドに渡し、そのメソッドをaggregate()にチェーンします。$graphLookup 演算子は、100 メガバイトという厳格なメモリ制限があり、
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"))
集計の説明
MongoDB が操作を実行する方法に関する情報を表示するには、 MongoDBクエリ プランナーにそれを説明するように指示できます。MongoDB が操作 を説明すると、実行プランとパフォーマンス統計が返されます。実行プランは、 MongoDB が操作を完了できる潜在的な方法です。 MongoDB に操作を説明するよう指示すると、 MongoDBが実行したプランと拒否された実行プランの両方がデフォルトで返されます。
集計操作 を説明するには、explain() メソッドを aggregate() メソッドに連鎖させます。 冗長レベルを explain() に渡すことで、メソッドが返す情報のタイプと量が変更されます。 冗長 の詳細については、 MongoDB Serverマニュアルの「 冗長モード 」を参照してください。
次の例では、 MongoDBExplainVerbosity.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"))
MongoDB Search で全文検索を実行する
1 つ以上のフィールドの全文検索を指定するには、$searchパイプラインステージを作成します。 Scalaドライバーは、このステージを作成するための Aggregates.search()ヘルパーメソッドを提供します。 search() メソッドには次の引数が必要です。
SearchOperatorインスタンス: 検索するフィールドとテキストを指定します。SearchOptionsインスタンス: 全文検索するオプションを指定します。使用するMongoDB検索インデックスの名前にindexオプションを設定する必要があります。
この例では、次のアクションを実行するためのパイプラインステージを作成しています。
nameフィールドで"Salt"という単語を含むテキストを検索一致するドキュメントの
_idとnameの値のみを予測
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"))
重要
上記の例を実行するには、nameフィールドをカバーする restaurantsコレクションにMongoDB Searchインデックスを作成する必要があります。次に、"<search index name>" プレースホルダーをインデックスの名前に置き換えます。MongoDB Search インデックスの詳細については、MongoDB Search と MongoDB ベクトル検索インデックスのガイドを参照してください。
検索演算子ヘルパー メソッド
Scalaドライバーは次の演算子のヘルパーメソッドを提供します。
演算子 | 説明 |
|---|---|
不完全な入力 string からの文字シーケンスを含む単語またはフレーズを検索します。 | |
2 つ以上の演算子を 1 つのクエリに結合します。 | |
フィールドが指定した値と一致するかどうかを確認します。 | |
指定されたインデックス付きフィールド名へのパスがドキュメント内に存在するかどうかをテストします。 | |
指定されたパスにあるBSON番号、日付、ブール値、ObjectId、uuid、または string 値の配列を検索し、フィールドの値が指定された配列内の任意の値と等しいドキュメントを返します。 | |
入力ドキュメントに類似するドキュメントを返します。 | |
数値、日付、 GeoJSONポイント値のクエリとスコアリングをサポートします。 | |
インデックス構成で指定されたアナライザを使用して、順序付けられたタームのシーケンスを含むドキュメントを検索します。 | |
インデックス付きフィールドと値の組み合わせのクエリをサポートします。 | |
数値、日付、string 値のクエリとスコアリングをサポートします。 | |
クエリフィールドを 正規式として解釈します。 | |
インデックス構成で指定したアナライザを使用して全文検索を実行します。 | |
検索stringに任意の文字と一致する特殊文字を使用するクエリを有効にします。 |
パイプライン検索ステージの例
この例を実行する前に、moviesコレクションに次の定義を持つMongoDB検索インデックスを作成する必要があります。
{ "mappings": { "dynamic": true, "fields": { "title": { "analyzer": "lucene.keyword", "type": "string" }, "genres": { "normalizer": "lowercase", "type": "token" } } } }
MongoDB Search インデックスの作成の詳細については、MongoDB Search と 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"))
MongoDB 検索するヘルパーメソッドの詳細については、ドライバー Core API ドキュメントの SearchOperator インターフェース参照を参照してください。
詳細情報
MongoDB Server マニュアル
このガイドで説明されているトピックについて詳しくは、 MongoDB Serverマニュアルの次のページ を参照してください。
集計ステージの完全なリストについては、MongoDB Serverマニュアルの集計ステージを参照してください。
集計パイプラインの組み立てと例については、集計パイプラインを参照してください。
パイプラインステージの作成の詳細については、集計ステージを参照してください。
MongoDB 操作の説明の詳細については、「出力とクエリ プランの説明 」を参照してください。
API ドキュメント
このガイドで説明するメソッドとタイプの詳細については、次の API ドキュメントを参照してください。