集計ビルダ
項目一覧
Overview
このガイドでは、 集計 の使用方法を学習できます クラスは、MongoDB Java ドライバーに 集計パイプライン ステージ を構築する静的ファクトリー メソッドを提供します。
集計の詳細については、 集計ガイド をご覧ください。
Tip
簡潔にするために、次のクラスのメソッドを静的にインポートして、クエリをより簡潔にすることを選択できます。
Aggregates
Filters
Projections
Sorts
Accumulators
import static com.mongodb.client.model.Aggregates.*; import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Projections.*; import static com.mongodb.client.model.Sorts.*; import static com.mongodb.client.model.Accumulators.*; import static java.util.Arrays.asList;
このページの例では、 asList()
メソッドの静的インポートに加えて、これらの静的インポートを前提としています。
これらのメソッドを使用してパイプライン ステージを構築し、それらをリストとして集計で指定します。
Bson matchStage = match(eq("some_field", "some_criteria")); Bson sortByCountStage = sortByCount("some_field"); collection.aggregate(asList(matchStage, sortByCountStage)).forEach(doc -> System.out.println(doc));
一致
match()
メソッドを使用して、指定されたクエリフィルターと受信ドキュメントを照合する$matchパイプライン ステージを作成し、一致しないドキュメントをフィルタリングで除外します。
Tip
フィルターは、 Bson
を実装する任意のクラスのインスタンスにすることができますが、フィルタークラスの使用と組み合わせると便利です。
次の例では、 title
フィールドが「シャードのシャーディング」に等しいすべてのドキュメントに一致するパイプライン ステージを作成します。
match(eq("title", "The Shawshank Redemption"));
プロジェクト
project()
メソッドを使用して、指定されたドキュメント フィールドをプロジェクションする$projectパイプライン ステージを作成します。 集計でのフィールド プロジェクションは、クエリの フィールド プロジェクションと同じルールに従います。
Tip
プロジェクションはBson
を実装する任意のクラスのインスタンスでもかまいませんが、 の使用と組み合わせると便利です。
次の例では、 _id
フィールドを除外するものの、 title
フィールドとplot
フィールドを含むパイプライン ステージを作成します。
project(fields(include("title", "plot"), excludeId()));
計算フィールドのプロジェクション
$project
ステージは計算フィールドもプロジェクションできます。
次の例では、 rated
フィールドをrating
という新しいフィールドにプロジェクションし、フィールドの名前を実質的に変更するパイプライン ステージを作成します。
project(fields(computed("rating", "$rated"), excludeId()));
サンプル
sample()
メソッドを使用して、入力からドキュメントをランダムに選択するための$sampleパイプライン ステージを作成します。
次の例では、5 つのドキュメントをランダムに選択するパイプライン ステージを作成します。
sample(5);
Sort
sort()
メソッドを使用して、指定された条件で並べ替えるための$sortパイプライン ステージを作成します。
Tip
並べ替え条件はBson
を実装するクラスのインスタンスでもかまいませんが、 並べ替え の使用と組み合わせると便利です。
次の例では、 year
フィールドの値に従って降順でソートし、次にtitle
フィールドの値の昇順でソートするパイプライン ステージを作成します。
sort(orderBy(descending("year"), ascending("title")));
スキップ
skip()
メソッドを使用して$skipパイプライン ステージを作成し、ドキュメントを次のステージに渡す前に指定された数のドキュメントをスキップします。
次の例では、最初の5
ドキュメントをスキップするパイプライン ステージを作成しています。
skip(5);
Limit
次のステージに渡されるドキュメントの数を制限するには、 $limitパイプライン ステージを使用します。
次の例では、ドキュメント数を10
に制限するパイプライン ステージを作成しています。
limit(10);
ルックアップ
lookup()
メソッドを使用して$lookupパイプライン ステージを作成し、2 つのコレクション間で結合と非相関サブクエリを実行します。
左外部結合
次の例では、 コレクションと コレクション間で左外部結合を実行するパイプライン ステージを作成します。movies
comments
movies
の_id
フィールドをcomments
のmovie_id
フィールドに結合しますjoined_comments
フィールドに結果を出力します。
lookup("comments", "_id", "movie_id", "joined_comments");
完全結合と非相関サブクエリ
次の例では、食材と利用可能な数量が注文数量を満たせるかどうかで、 orders
とwarehouses
の 2 つのコレクションを結合するパイプライン ステージを作成します。
List<Variable<String>> variables = asList(new Variable<>("order_item", "$item"), new Variable<>("order_qty", "$ordered")); List<Bson> pipeline = asList( match(expr(new Document("$and", asList(new Document("$eq", asList("$$order_item", "$stock_item")), new Document("$gte", asList("$instock", "$$order_qty")))))), project(fields(exclude("stock_item"), excludeId()))); List<Bson> innerJoinLookup = lookup("warehouses", variables, pipeline, "stockdata");
グループ
group()
メソッドを使用して$groupパイプライン ステージを作成し、指定された式でドキュメントをグループ化し、個別のグループごとにドキュメントを出力します。
Tip
ドライバーには アキュムレータ が含まれます サポートされているアキュムレータごとに静的ファクトリー メソッドを持つ クラス。
次の例では、 customerId
フィールドの値でドキュメントをグループ化するパイプライン ステージを作成します。 各グループは、 quantity
フィールドの値の合計と平均をtotalQuantity
フィールドとaverageQuantity
フィールドに累積します。
group("$customerId", sum("totalQuantity", "$quantity"), avg("averageQuantity", "$quantity"));
アキュムレータ演算子の詳細については、サーバー マニュアルの「アキュムレータ 」セクションを参照してください。
Ticket-N アキュムレータ
選択可能アキュムレータ は、特定の順序指定された上位要素と最下位要素を返す集計アキュムレーション演算子です。 次のいずれかのビルダを使用して、集計アキュムレーション演算子を作成します。
Tip
これらの Ticket-n アキュムレータを使用して集計操作を実行できるのは、MongoDB v5.2 以降を実行している場合のみです。
アキュムレータ演算子を使用できる集計パイプライン ステージについては、サーバー マニュアルの「アキュムレータ 」セクションを参照してください。
MinN
minN()
ビルダーは$minNアキュムレータを作成します。これはグループのn
最小値を含むドキュメントのデータを返します。
Tip
$minN
と$bottomN
のアキュムレータも同様のタスクを実行できます。 それぞれの推奨使用量については、「 $minN と $bottomN アキュムレータの比較」を参照してください。
次の例では、 minN()
メソッドを使用して、 year
でグループ化された映画の最小の 3 つのimdb.rating
値を返す方法を示しています。
group( "$year", minN( "lowest_three_ratings", new BsonString("$imdb.rating"), 3 ));
minN() API ドキュメント を参照 詳しくは、 を参照してください。
MaxN
maxN()
アキュムレータは、グループの最大値n
を含むドキュメントのデータを返します。
次の例では、 maxN()
メソッドを使用して、 year
でグループ化された映画の上位 2 つのimdb.rating
値を返す方法を示します。
group( "$year", maxN( "highest_two_ratings", new BsonString("$imdb.rating"), 2 ));
maxN() API ドキュメント を参照してください 詳しくは、 を参照してください。
FirstN
firstN()
アキュムレータは、指定されたソート順序の各グループの最初のn
ドキュメントのデータを返します。
Tip
$firstN
と$topN
のアキュムレータも同様のタスクを実行できます。 それぞれの推奨使用量については、「 $firstN と $topN アキュムレータの比較」を参照してください。
次の例では、 firstN()
メソッドを使用して、 ステージになった順序に基づいて最初の 4 つの映画のtitle
値をyear
でグループ化して返す方法を示しています。
group( "$year", firstN( "first_four_movies", new BsonString("$title"), 4 ));
firstN() API ドキュメント を参照してください 詳しくは、 を参照してください。
LastN
lastN()
アキュムレータは、指定されたソート順序の各グループ内の最後のn
ドキュメントのデータを返します。
次の例では、 lastN()
メソッドを使用して、ステージに入る順序に基づいて、最後の 3 つの映画のtitle
値をyear
でグループ化して表示する方法を示します。
group( "$year", lastN( "last_three_movies", new BsonString("$title"), 3 ));
lastN() API ドキュメント を参照 詳しくは、 を参照してください。
top
top()
アキュムレータは、指定ソート順に基づいてグループ内の最初のドキュメントのデータを返します。
top()
次の例では、title
imdb.rating
imdb.rating
メソッドを使用して、 でグループ化された に基づいて最高評価の映画の とyear
の値を返す方法を示します。
group( "$year", top( "top_rated_movie", descending("imdb.rating"), asList(new BsonString("$title"), new BsonString("$imdb.rating")) ));
top() API ドキュメント を参照してください 詳しくは、 を参照してください。
TopN
topN()
アキュムレータは、指定されたフィールドの最大のn
値を含むドキュメントのデータを返します。
Tip
$firstN
と$topN
のアキュムレータも同様のタスクを実行できます。 それぞれの推奨使用量については、「 $firstN と $topN アキュムレータの比較」を参照してください。
次の例では、 topN()
メソッドを使用して、 year
でグループ化されたruntime
値に基づいて、最も長い 3 つの映画のtitle
とruntime
の値を返す方法を示します。
group( "$year", topN( "longest_three_movies", descending("runtime"), asList(new BsonString("$title"), new BsonString("$runtime")), 3 ));
トップN() API ドキュメント を参照してください 詳しくは、 を参照してください。
下部
bottom()
アキュムレータは、指定されたソート順序に基づいてグループ内の最後のドキュメントのデータを返します。
次の例では、 bottom()
メソッドを使用して、 year
でグループ化されたruntime
値に基づいて最も短い映画のtitle
とruntime
の値を返す方法を示します。
group( "$year", bottom( "shortest_movies", descending("runtime"), asList(new BsonString("$title"), new BsonString("$runtime")) ));
bottom() API ドキュメント を参照してください 詳しくは、 を参照してください。
bottomN
bottomN()
アキュムレータは、指定されたフィールドの最小のn
値を含むドキュメントのデータを返します。
Tip
$minN
と$bottomN
のアキュムレータも同様のタスクを実行できます。 それぞれの推奨使用量については、「 $minN と $bottomN アキュムレータの比較」を参照してください。
次の例では、 bottomN()
メソッドを使用して、 year
でグループ化されたimdb.rating
値に基づき、評価が最も低い 2 つの映画のtitle
とimdb.rating
の値を返す方法を示しています。
group( "$year", bottomN( "lowest_rated_two_movies", descending("imdb.rating"), asList(new BsonString("$title"), new BsonString("$imdb.rating")), 2 ));
bottomN() API ドキュメント を参照してください 詳しくは、 を参照してください。
Unwind
unwind()
メソッドを使用して$unwindパイプライン ステージを作成し、入力ドキュメントから配列フィールドを分解し、配列要素ごとに出力ドキュメントを作成します。
次の例では、 sizes
配列内の各要素のドキュメントを作成します。
unwind("$sizes");
配列フィールドの欠落値またはnull
値、または配列が空のドキュメントを保持するには:
unwind("$sizes", new UnwindOptions().preserveNullAndEmptyArrays(true));
配列インデックスを含めるには、この例では"position"
というフィールドに含めます。
unwind("$sizes", new UnwindOptions().includeArrayIndex("position"));
アウト
out()
メソッドを使用して、すべてのドキュメントを同じデータベース内の指定されたコレクションに書込む$outパイプライン ステージを作成します。
重要
$out
ステージは、すべての集計パイプラインの 最後のステージ である必要があります。
次の例では、パイプラインの結果をauthors
コレクションに書き込みます。
out("authors");
merge
merge()
メソッドを使用して、すべてのドキュメントを指定されたコレクションにマージする$mergeパイプライン ステージを作成します。
重要
$merge
ステージは、すべての集計パイプラインの 最後のステージ である必要があります。
次の例では、デフォルトの オプションを使用してパイプラインをauthors
コレクションにマージします。
merge("authors");
次の例では、 date
とcustomerId
の両方が一致する場合はドキュメントを置き換え、それ以外の場合はドキュメントを挿入するオプションを使用して、パイプラインをreporting
データベースのcustomers
コレクションにマージします。
merge(new MongoNamespace("reporting", "customers"), new MergeOptions().uniqueIdentifier(asList("date", "customerId")) .whenMatched(MergeOptions.WhenMatched.REPLACE) .whenNotMatched(MergeOptions.WhenNotMatched.INSERT));
GraphLookup
graphLookup()
メソッドを使用して、指定されたコレクションに対して再帰検索を実行し、1 つのドキュメント内の指定されたフィールドを別のドキュメントの指定されたフィールドと照合する$graphLookupパイプライン ステージを作成します。
次の例では、 contacts
コレクション内のユーザーのソーシャル ネットワーク グラフを計算し、 friends
フィールドの値をname
フィールドに再帰的に照合します。
graphLookup("contacts", "$friends", "friends", "name", "socialNetwork");
GraphLookupOptions
を使用すると、必要に応じて再帰する深度と、深度フィールドの名前を指定できます。 この例では、 $graphLookup
は最大 2 回再帰し、すべてのドキュメントの再帰深度情報を持つdegrees
というフィールドを作成します。
graphLookup("contacts", "$friends", "friends", "name", "socialNetwork", new GraphLookupOptions().maxDepth(2).depthField("degrees"));
GraphLookupOptions
を使用すると、MongoDB が検索にドキュメントを含めるために一致する必要があるフィルターを指定できます。 この例では、 hobbies
フィールドに「golf」が含まれるリンクのみが含まれます。
graphLookup("contacts", "$friends", "friends", "name", "socialNetwork", new GraphLookupOptions().maxDepth(1).restrictSearchWithMatch(eq("hobbies", "golf")));
カウントによる並べ替え
sortByCount()
メソッドを使用して、特定の式でドキュメントをグループ化し、これらのグループをカウントで降順にソートする$sortByCountパイプライン ステージを作成します。
Tip
$sortByCount
ステージは、 $sum
アキュムレータとそれに続く$sort
ステージを持つ$group
ステージと同一です。
[ { "$group": { "_id": <expression to group on>, "count": { "$sum": 1 } } }, { "$sort": { "count": -1 } } ]
次の例では、ドキュメントをフィールドx
の切り捨てられた値でグループ化し、個別の値ごとにカウントを計算します。
sortByCount(new Document("$floor", "$x"));
ReplaceRoot
replaceRoot()
メソッドを使用して、各入力ドキュメントを指定されたドキュメントで置き換える$replaceRootパイプライン ステージを作成します。
次の例では、各入力ドキュメントをspanish_translation
フィールドにあるネストされたドキュメントに置き換えます。
replaceRoot("$spanish_translation");
AddFields
addFields()
メソッドを使用して、ドキュメントに新しいフィールドを追加する$addFieldsパイプライン ステージを作成します。
Tip
フィールドの包含または除外をプロジェクトしない場合は、 $addFields
を使用します。
次の例では、入力ドキュメントにa
とb
の 2 つの新しいフィールドを追加します。
addFields(new Field("a", 1), new Field("b", 2));
数
count()
メソッドを使用して、ステージに入るドキュメントの数をカウントし、その値を指定されたフィールド名に割り当てる$countパイプライン ステージを作成します。 If you do not specify a field, count()
defaults the field name to "count".
Tip
$count
ステージは、次の構文アプリです。
{ "$group":{ "_id": 0, "count": { "$sum" : 1 } } }
次の例では、「total」というフィールドに受信したドキュメントの数を出力するパイプライン ステージを作成します。
count("total");
バケット
bucket()
メソッドを使用して、事前定義された境界値の周囲のデータのバケットを自動化する$bucketパイプライン ステージを作成します。
次の例では、受信したドキュメントをscreenSize
フィールドの値に基づいてグループ化するパイプライン ステージを作成します。このステージは下限を含み、上限を含まないものです。
bucket("$screenSize", asList(0, 24, 32, 50, 70, 200));
指定された境界外の値のデフォルト バケットを指定し、追加のアキュムレータを指定するには、 BucketOptions
クラスを使用します。
次の例では、 screenSize
フィールドの値に基づいて受信ドキュメントをグループ化し、各バケットに含まれるドキュメントの数をカウントし、 screenSize
の値をmatches
というフィールドにプッシュして、次を取得するパイプライン ステージを作成します: 「70」を超える任意の画面サイズを、平均して大きな画面サイズ用の「mongostat」と呼ばれるバケットに格納します。
Tip
ドライバーには アキュムレータ が含まれます サポートされているアキュムレータごとに静的ファクトリー メソッドを持つ クラス。
bucket("$screenSize", asList(0, 24, 32, 50, 70), new BucketOptions().defaultBucket("monster").output(sum("count", 1), push("matches", "$screenSize")));
BucketAuto
bucketAuto()
メソッドを使用して$bucketAutoパイプライン ステージを作成します。このステージは、指定された数のバケットにドキュメントを均等に分散するために各バケットの境界を自動的に決定します。
次の例では、 price
フィールドの値を使用して、ドキュメントを作成し10個のバケットに均等に分散するパイプライン ステージを作成します。
bucketAuto("$price", 10);
希望数値 BucketAutoOptions
を指定するには、 クラスを使用します に基づくスキームを使用して境界値を設定し、追加のアキュムレータを指定します。
次の例では、 price
フィールドの値を使用して10個のバケットにドキュメントを作成し、均等に分散するパイプライン ステージを作成し、バケット境界を 2 の累乗(2、4、8、16、...)に設定します。 。 また、各バケット内のドキュメント数をカウントし、 avgPrice
という新しいフィールドでそれらの平均price
を計算します。
Tip
ドライバーには アキュムレータ が含まれます サポートされているアキュムレータごとに静的ファクトリー メソッドを持つ クラス。
bucketAuto("$price", 10, new BucketAutoOptions().granularity(BucketGranularity.POWERSOF2) .output(sum("count", 1), avg("avgPrice", "$price")));
Facet
facet()
メソッドを使用して$facetパイプライン ステージを作成し、並列パイプラインの定義を可能にします。
次の例では、2 つの並列集計を実行するパイプライン ステージを作成しています。
最初の集計では、受信したドキュメントを
attributes.screen_size
フィールドに従って 5 つのグループに分散します。2 番目の集計では、すべてのメーカーをカウントし、上位5に限定したその数を返します。
facet(new Facet("Screen Sizes", bucketAuto("$attributes.screen_size", 5, new BucketAutoOptions().output(sum("count", 1)))), new Facet("Manufacturer", sortByCount("$attributes.manufacturer"), limit(5)));
SetWindowFields
setWindowFields()
メソッドを使用して$setWindowFieldsパイプライン ステージを作成し、ウィンドウ演算子がコレクション内の指定された範囲のドキュメントに対して操作を実行できるようにします。
次の例では、 フィールドと フィールドに表示されるより詳細な測定値から、各地域の過去 1 か月の累積降量と平均温度を計算するパイプライン ステージを作成します。rainfall
temperature
Window pastMonth = Windows.timeRange(-1, MongoTimeUnit.MONTH, Windows.Bound.CURRENT); setWindowFields("$localityId", Sorts.ascending("measurementDateTime"), WindowOutputFields.sum("monthlyRainfall", "$rainfall", pastMonth), WindowOutputFields.avg("monthlyAvgTemp", "$temperature", pastMonth));
密度
densify()
メソッドを使用して、指定された間隔にわたるドキュメントのシーケンスを生成する$densifyパイプライン ステージを作成します。
Tip
$densify()
集計ステージは MongoDB v5.1 以降を実行している場合にのみ使用できます。
Atlas サンプル 気象 データセットから取得され、1 時間間隔で配置された同様のposition
フィールドの測定値を含む次のドキュメントを検討してください。
Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }} Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}
これらのドキュメントに対して次のアクションを実行するパイプライン ステージを作成する必要があるとします。
ts
値がまだ存在しないドキュメントを 15 分ごとに追加します。ドキュメントを
position
フィールドでグループ化します。
これらのアクションを実行するdensify()
集計ステージ ビルダへの呼び出しは、次のようになります。
densify( "ts", DensifyRange.partitionRangeWithStep(15, MongoTimeUnit.MINUTE), DensifyOptions.densifyOptions().partitionByFields("position.coordinates"));
次の出力では、既存のドキュメント間で 15 分ごとのts
値を含む、 集計ステージによって生成されたドキュメントが強調表示されています。
Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:15:00 EST 1984 }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:30:00 EST 1984 }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:45:00 EST 1984 }} Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}
詳細は、 densify パッケージ API ドキュメント を参照してください 詳しくは、 を参照してください。
Fill
fill()
メソッドを使用して、 null
と欠落しているフィールド値を入力する$fillパイプライン ステージを作成します。
Tip
$fill()
集計ステージは MongoDB v5.3 以降を実行している場合にのみ使用できます。
1 時間ごとの温度と温度の測定値を含む次のドキュメントを検討してください。
Document{{_id=6308a..., hour=1, temperature=23C, air_pressure=29.74}} Document{{_id=6308b..., hour=2, temperature=23.5C}} Document{{_id=6308c..., hour=3, temperature=null, air_pressure=29.76}}
次のように、ドキュメントに欠落している温度と温度のデータ ポイントを入力する必要があるとします。
線形補間 を使用して値を計算し、
air_pressure
フィールドに時間 "2" を入力します。欠落している
temperature
値を「23.6C」に設定します 時間の「3」。
これらのアクションを実行するfill()
集計ステージ ビルダへの呼び出しは次のようになります。
fill( FillOptions.fillOptions().sortBy(ascending("hour")), FillOutputField.value("temperature", "23.6C"), FillOutputField.linear("air_pressure") );
次の出力では、 集計ステージによって入力されるフィールドを含むドキュメントが強調表示されています。
Document{{_id=6308a..., hour=1, temperature=23C, air_pressure=29.74}} Document{{_id=6308b..., hour=2, temperature=23.5C, air_pressure=29.75}} Document{{_id=6308c..., hour=3, temperature=23.6C, air_pressure=29.76}}
フィルター パッケージ API ドキュメント を参照してください 詳しくは、 を参照してください。
Atlas 全文検索
search()
メソッドを使用して、1 つ以上のフィールドの全文検索を指定する$searchパイプライン ステージを作成します。
Tip
MongoDB v4.2 以降の Atlas でのみ利用可能
この集計パイプライン演算子は、 インデックス によってカバーされているMongoDB Atlas v4.2 以降を実行しているAtlas Search クラスターでホストされているコレクションでのみ使用できます。必要な設定とこの演算子の機能の詳細については、 Atlas Searchのドキュメントを参照してください。
次の例では、 title
フィールドで「feature」という単語を含むテキストを検索するパイプライン ステージを作成します。
Bson textSearch = Aggregates.search( SearchOperator.text( SearchPath.fieldPath("title"), "Future"));
ビルダの詳細については、 検索パッケージ API ドキュメントを参照してください。
Atlas Search メタデータ
searchMeta()
メソッドを使用して、Atlas 全文検索クエリの結果のメタデータ部分のみを返す$searchMetaパイプライン ステージを作成します。
Tip
MongoDB v4.4.11 以降の Atlas でのみ利用可能
この集計パイプライン演算子は、v 4.4.11以降を実行しているMongoDB Atlasクラスターでのみ使用できます。 利用可能なバージョンの詳細なリストについては、 $searchMeta に関する MongoDB Atlas のドキュメント を参照してください。
次の例では、Atlas Search 集計ステージのcount
メタデータを示しています。
Aggregates.searchMeta( SearchOperator.near(2010, 1, SearchPath.fieldPath("year")));
このヘルパーの詳細については、 searchMeta() API ドキュメント を参照してください。