アグリゲーションフレームワークのサポート
Spring Data MongoDB は、バージョン 2.2 で MongoDB に導入された集約 フレームワークのサポートを提供します。
詳細については、MongoDB の集約フレームワークおよびその他のデータ集約ツールの完全なリファレンスドキュメント (英語) を参照してください。
基本概念
Spring Data MongoDB の集約 フレームワークサポートは、次の主要な抽象化に基づいています: Aggregation
(Javadoc) および AggregationResults
(Javadoc) 。
Aggregation
Aggregation
は MongoDBaggregate
操作を表し、集約パイプライン命令の記述を保持します。集計は、Aggregation
クラスの適切なnewAggregation(…)
静的ファクトリメソッドを呼び出すことによって作成されます。このメソッドは、AggregateOperation
のリストとオプションの入力クラスを受け取ります。実際の集約操作は、目的の出力クラスをパラメーターとして受け取る
MongoTemplate
のaggregate
メソッドによって実行されます。TypedAggregation
TypedAggregation
は、Aggregation
と同様に、集約パイプラインの命令と、ドメインプロパティを実際のドキュメントフィールドにマッピングするために使用される入力型への参照を保持します。実行時に、潜在的な
@Field
アノテーションを考慮して、フィールド参照が指定された入力型に対してチェックされます。
3.2 で変更され、存在しないプロパティを参照してもエラーが発生しなくなりました。以前の動作を復元するには、AggregationOptions
の strictMapping
オプションを使用します。
AggregationDefinition
AggregationDefinition
は MongoDB 集約パイプライン操作を表し、この集約ステップで実行する必要がある処理を記述します。AggregationDefinition
を手動で作成することもできますが、Aggregate
クラスによって提供される静的ファクトリメソッドを使用してAggregateOperation
を構築することをお勧めします。AggregationResults
AggregationResults
は、集約操作の結果のコンテナーです。これにより、マッピングされたオブジェクトおよび集約に関するその他の情報へのDocument
の形式で、生の集約結果へのアクセスが提供されます。次のリストは、MongoDB 集約 フレームワークの Spring Data MongoDB サポートを使用する標準的な例を示しています。
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; Aggregation agg = newAggregation( pipelineOP1(), pipelineOP2(), pipelineOPn() ); AggregationResults<OutputType> results = mongoTemplate.aggregate(agg, "INPUT_COLLECTION_NAME", OutputType.class); List<OutputType> mappedResult = results.getMappedResults();
入力クラスを newAggregation
メソッドの最初のパラメーターとして指定すると、MongoTemplate
はこのクラスから入力コレクションの名前を派生することに注意してください。それ以外の場合、入力クラスを指定しない場合は、入力コレクションの名前を明示的に指定する必要があります。入力クラスと入力コレクションの両方が指定された場合は、後者が優先されます。
サポートされている集約操作とステージ
MongoDB 集約 フレームワークは、次の型の集約ステージと操作を提供します。
addFields -
AddFieldsOperation
バケット /bucketAuto -
BucketOperation
/BucketAutoOperation
カウント -
CountOperation
高密度化する -
DensifyOperation
ファセット -
FacetOperation
geoNear -
GeoNearOperation
graphLookup -
GraphLookupOperation
グループ -
GroupOperation
限界 -
LimitOperation
見上げる -
LookupOperation
一致 -
MatchOperation
マージ -
MergeOperation
プロジェクト -
ProjectionOperation
編集する -
RedactOperation
replaceRoot -
ReplaceRootOperation
サンプル -
SampleOperation
セット -
SetOperation
setWindowFields -
SetWindowFieldsOperation
skip -
SkipOperation
並べ替え / 並べ替え数 -
SortOperation
/SortByCountOperation
unionWith -
UnionWithOperation
設定を解除する -
UnsetOperation
くつろぐ -
UnwindOperation
サポートされていない集約ステージ (MongoDB Atlas の $search (英語) など) は、
|
このドキュメントの記載時点では、Spring Data MongoDB では次の集計演算子がサポートされています。
集合集計演算子 |
|
グループ / アキュムレータ集計演算子 |
|
算術集計演算子 |
|
文字列集約演算子 |
|
比較集計演算子 |
|
配列集約演算子 |
|
リテラル演算子 |
|
日付集計演算子 |
|
変数演算子 |
|
条件付き集計演算子 |
|
型集計演算子 |
|
集計演算子の変換 |
|
オブジェクト集約演算子 |
|
スクリプト集約演算子 |
|
※操作は Spring Data MongoDB によりマッピングまたは追加されます。
ここにリストされていない集計操作は、現在 Spring Data MongoDB ではサポートされていないことに注意してください。比較集計演算子は Criteria
式として表されます。
射影式
射影式は、特定の集計ステップの結果であるフィールドを定義するために使用されます。射影式は、String
オブジェクトのリストまたは集計フレームワーク Fields
オブジェクトを渡すことにより、Aggregation
クラスの project
メソッドを通じて定義できます。and(String)
メソッドを使用して流れるような API を介して追加のフィールドを使用して射影を継承したり、as(String)
メソッドを使用してエイリアスを作成したりできます。集計フレームワークの Fields.field
静的ファクトリメソッドを使用して、エイリアスを持つフィールドを定義することもできます。これを使用して、新しい Fields
インスタンスを構築できます。後の集計段階での射影フィールドへの参照は、含まれるフィールドまたはそのエイリアス (新しく定義されたフィールドとそのエイリアスを含む) のフィールド名に対してのみ有効です。射影に含まれていないフィールドは、後の集計段階では参照できません。次のリストは射影式の例を示しています。
// generates {$project: {name: 1, netPrice: 1}}
project("name", "netPrice")
// generates {$project: {thing1: $thing2}}
project().and("thing1").as("thing2")
// generates {$project: {a: 1, b: 1, thing2: $thing1}}
project("a","b").and("thing1").as("thing2")
// generates {$project: {name: 1, netPrice: 1}}, {$sort: {name: 1}}
project("name", "netPrice"), sort(ASC, "name")
// generates {$project: {name: $firstname}}, {$sort: {name: 1}}
project().and("firstname").as("name"), sort(ASC, "name")
// does not work
project().and("firstname").as("name"), sort(ASC, "firstname")
プロジェクト操作のその他の例は、AggregationTests
クラスにあります。射影式に関する詳細については、MongoDB Aggregation フレームワークリファレンスドキュメントの対応するセクション (英語) を参照してください。
ファセット分類
バージョン 3.4 の時点で、MongoDB は集約 フレームワークを使用したファセット分類をサポートしています。ファセット分類では、完全な分類エントリを作成するために結合される意味論的なカテゴリ (一般またはサブジェクト固有のいずれか) が使用されます。集約パイプラインを流れるドキュメントはバケットに分類されます。多面的な分類により、入力ドキュメントを複数回取得することなく、同じ入力ドキュメントのセットに対してさまざまな集計を行うことができます。
バケット
バケット操作では、指定された式とバケット境界に基づいて、受信ドキュメントをバケットと呼ばれるグループに分類します。バケット操作には、グループ化フィールドまたはグループ化式が必要です。これらは、Aggregate
クラスの bucket()
および bucketAuto()
メソッドを使用して定義できます。BucketOperation
および BucketAutoOperation
は、入力ドキュメントの集計式に基づいて累積を公開できます。with … ()
メソッドと andOutput(String)
メソッドを使用すると、流れるような API を通じて追加パラメーターを使用してバケット操作を継承できます。as(String)
メソッドを使用して、操作に別名を付けることができます。各バケットは出力内でドキュメントとして表されます。
BucketOperation
は、定義された境界セットを使用して、受信ドキュメントをこれらのカテゴリにグループ化します。境界を並べ替える必要があります。次のリストは、バケット操作の例をいくつか示しています。
// generates {$bucket: {groupBy: $price, boundaries: [0, 100, 400]}}
bucket("price").withBoundaries(0, 100, 400);
// generates {$bucket: {groupBy: $price, default: "Other" boundaries: [0, 100]}}
bucket("price").withBoundaries(0, 100).withDefault("Other");
// generates {$bucket: {groupBy: $price, boundaries: [0, 100], output: { count: { $sum: 1}}}}
bucket("price").withBoundaries(0, 100).andOutputCount().as("count");
// generates {$bucket: {groupBy: $price, boundaries: [0, 100], 5, output: { titles: { $push: "$title"}}}
bucket("price").withBoundaries(0, 100).andOutput("title").push().as("titles");
BucketAutoOperation
は、ドキュメントを指定された数のバケットに均等に分散することを目的として境界を決定します。BucketAutoOperation
はオプションで、計算された境界エッジが推奨される丸め番号または 10 の累乗で終了するようにするために使用する優先数値 [Wikipedia] (英語) 系列を指定する粒度値を受け取ります。次のリストは、バケット操作の例を示しています。
// generates {$bucketAuto: {groupBy: $price, buckets: 5}}
bucketAuto("price", 5)
// generates {$bucketAuto: {groupBy: $price, buckets: 5, granularity: "E24"}}
bucketAuto("price", 5).withGranularity(Granularities.E24).withDefault("Other");
// generates {$bucketAuto: {groupBy: $price, buckets: 5, output: { titles: { $push: "$title"}}}
bucketAuto("price", 5).andOutput("title").push().as("titles");
バケットに出力フィールドを作成するには、バケット操作で AggregationExpression
~ andOutput()
および SpEL 式~ andOutputExpression()
を使用できます。
バケット式の詳細については、MongoDB Aggregation フレームワークリファレンスドキュメントの $bucket
セクション (英語) および $bucketAuto
セクション (英語) を参照してください。
多面的な集約
複数の集計パイプラインを使用して、単一の集計ステージ内の複数のディメンション (またはファセット) にわたるデータを特徴付ける多面的な集計を作成できます。多面的な集計では、データの参照と分析をガイドする複数のフィルターと分類が提供されます。ファセットの一般的な実装は、製品の価格、メーカー、サイズ、その他の要素にフィルターを適用して検索結果を絞り込む方法を提供しているオンライン小売業者の数です。
FacetOperation
は、Aggregation
クラスの facet()
メソッドを使用して定義できます。and()
メソッドを使用して、複数の集計パイプラインでカスタマイズできます。各サブパイプラインには出力ドキュメント内に独自のフィールドがあり、その結果がドキュメントの配列として保存されます。
サブパイプラインは、グループ化する前に入力ドキュメントを投影およびフィルタリングできます。一般的な使用例には、分類前の日付部分の抽出や計算が含まれます。次のリストは、ファセット操作の例を示しています。
// generates {$facet: {categorizedByPrice: [ { $match: { price: {$exists : true}}}, { $bucketAuto: {groupBy: $price, buckets: 5}}]}}
facet(match(Criteria.where("price").exists(true)), bucketAuto("price", 5)).as("categorizedByPrice"))
// generates {$facet: {categorizedByCountry: [ { $match: { country: {$exists : true}}}, { $sortByCount: "$country"}]}}
facet(match(Criteria.where("country").exists(true)), sortByCount("country")).as("categorizedByCountry"))
// generates {$facet: {categorizedByYear: [
// { $project: { title: 1, publicationYear: { $year: "publicationDate"}}},
// { $bucketAuto: {groupBy: $price, buckets: 5, output: { titles: {$push:"$title"}}}
// ]}}
facet(project("title").and("publicationDate").extractYear().as("publicationYear"),
bucketAuto("publicationYear", 5).andOutput("title").push().as("titles"))
.as("categorizedByYear"))
ファセット操作の詳細については、MongoDB Aggregation フレームワークリファレンスドキュメントの $facet
セクション (英語) を参照してください。
数で並べ替え
カウントによる並べ替え操作では、指定された式の値に基づいて受信ドキュメントをグループ化し、各グループ内のドキュメントの数を計算し、結果をカウントで並べ替えます。ファセット分類を使用するときに並べ替えを適用するための便利なショートカットを提供します。カウントによる並べ替え操作には、グループ化フィールドまたはグループ化式が必要です。次のリストは、カウントによる並べ替えの例を示しています。
// generates { $sortByCount: "$country" }
sortByCount("country");
カウントによる並べ替え操作は、次の BSON (バイナリ JSON) と同等です。
{ $group: { _id: <expression>, count: { $sum: 1 } } }, { $sort: { count: -1 } }
射影式での Spring 式のサポート
ProjectionOperation
クラスおよび BucketOperation
クラスの andExpression
メソッドを通じて、射影式での SpEL 式の使用をサポートします。この機能を使用すると、目的の式を SpEL 式として定義できます。クエリを実行すると、SpEL 式は対応する MongoDB 射影式部分に変換されます。この配置により、複雑な計算を非常に簡単に表現できるようになります。
SpEL 式を使用した複雑な計算
次の SpEL 式を考えてみましょう。
1 + (q + 1) / (q - 1)
前述の式は、次の射影式部分に変換されます。
{ "$add" : [ 1, {
"$divide" : [ {
"$add":["$q", 1]}, {
"$subtract":[ "$q", 1]}
]
}]}
集約 フレームワークの例 5 および集約 フレームワークの例 6 で、より詳しいコンテキストの例を確認できます。サポートされている SpEL 式構成体のその他の使用例は、SpelExpressionTransformerUnitTests
で見つけることができます。
サポートされている SpEL 変換
SpEL 式 | Mongo 表情パーツ |
---|---|
a == b | {$eq: [$a、$b] } |
a != b | {$ne: [$a、$b] } |
a > b | {$gt: [$a、$b] } |
a >= b | {$gte: [$a、$b] } |
a < b | {$lt: [$a、$b] } |
⇐ b | {$lte: [$a、$b] } |
a + b | {$add: [$a、$b] } |
a - b | {$subtract: [$a、$b] } |
a * b | {$multiply: [$a、$b] } |
a/b | {$divide: [$a、$b] } |
a^b | {$pow: [$a、$b] } |
a % b | {$mod: [$a、$b] } |
a&&b | {$and: [$a、$b] } |
| | b | {$or: [$a、$b] } |
!a | {$not: [$a] } |
前の表に示した変換に加えて、new
などの標準 SpEL 操作を使用して、(たとえば) 配列を作成し、その名前 (その後に 括弧 で使用する引数が続く) を介して式を参照することができます。次の例は、この方法で配列を作成する方法を示しています。
// { $setEquals : [$a, [5, 8, 13] ] }
.andExpression("setEquals(a, new int[]{5, 8, 13})");
集約 フレームワークの例
このセクションの例では、MongoDB 集約 フレームワークと Spring Data MongoDB の使用パターンを示します。
集約 フレームワークの例 1
この入門例では、タグのリストを集約して、MongoDB コレクション ( tags
と呼ばれる) から特定のタグの出現数を降順でソートして取得します。この例では、グループ化、並べ替え、射影 (選択)、巻き戻し (結果の分割) の使用箇所を示します。
class TagCount {
String tag;
int n;
}
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
Aggregation agg = newAggregation(
project("tags"),
unwind("tags"),
group("tags").count().as("n"),
project("n").and("tag").previousOperation(),
sort(DESC, "n")
);
AggregationResults<TagCount> results = mongoTemplate.aggregate(agg, "tags", TagCount.class);
List<TagCount> tagCount = results.getMappedResults();
前述のリストでは、次のアルゴリズムが使用されています。
newAggregation
静的ファクトリメソッドを使用して新しい集約を作成し、これに集約操作のリストを渡します。これらの集約操作は、Aggregation
の集約パイプラインを定義します。project
操作を使用して、入力コレクションからtags
フィールド (文字列の配列) を選択します。unwind
操作を使用して、tags
配列内のタグごとに新しいドキュメントを生成します。group
操作を使用して、出現数を集約するtags
値ごとにグループを定義します (count
集約演算子を使用し、結果をn
という新しいフィールドに収集します)。n
フィールドを選択し、前のグループ操作 (したがってpreviousOperation()
の呼び出し) から生成された ID フィールドのエイリアスをtag
という名前で作成します。sort
操作を使用して、結果のタグのリストを出現回数に基づいて降順に並べ替えます。MongoTemplate
でaggregate
メソッドを呼び出し、作成されたAggregation
を引数として MongoDB に実際の集計操作を実行させます。
入力コレクションは、aggregate
メソッドの tags
パラメーターとして明示的に指定されることに注意してください。入力コレクションの名前が明示的に指定されていない場合、その名前は newAggreation
メソッドの最初のパラメーターとして渡される入力クラスから派生されます。
集約 フレームワークの例 2
この例は、MongoDB Aggregation フレームワークドキュメントの状態ごとの最大都市と最小都市 (英語) 例に基づいています。さまざまな MongoDB バージョンで安定した結果を生成するために、追加の並べ替えを追加しました。ここでは、集計フレームワークを使用して、各状態の人口別に最小都市と最大都市を返したいと考えています。この例では、グループ化、並べ替え、射影 (選択) を示します。
class ZipInfo {
String id;
String city;
String state;
@Field("pop") int population;
@Field("loc") double[] location;
}
class City {
String name;
int population;
}
class ZipInfoStats {
String id;
String state;
City biggestCity;
City smallestCity;
}
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
TypedAggregation<ZipInfo> aggregation = newAggregation(ZipInfo.class,
group("state", "city")
.sum("population").as("pop"),
sort(ASC, "pop", "state", "city"),
group("state")
.last("city").as("biggestCity")
.last("pop").as("biggestPop")
.first("city").as("smallestCity")
.first("pop").as("smallestPop"),
project()
.and("state").previousOperation()
.and("biggestCity")
.nested(bind("name", "biggestCity").and("population", "biggestPop"))
.and("smallestCity")
.nested(bind("name", "smallestCity").and("population", "smallestPop")),
sort(ASC, "state")
);
AggregationResults<ZipInfoStats> result = mongoTemplate.aggregate(aggregation, ZipInfoStats.class);
ZipInfoStats firstZipInfoStats = result.getMappedResults().get(0);
ZipInfo
クラスは、指定された入力コレクションの構造をマップすることに注意してください。ZipInfoStats
クラスは、目的の出力形式で構造体を定義します。
前述のリストでは次のアルゴリズムが使用されています。
group
操作を使用して、入力コレクションからグループを定義します。グループ化条件は、state
フィールドとcity
フィールドの組み合わせであり、グループの ID 構造を形成します。sum
演算子を使用して、グループ化された要素からpopulation
プロパティの値を集約し、結果をpop
フィールドに保存します。sort
操作を使用して、pop
、state
、city
フィールドで中間結果を昇順に並べ替えます。結果の最小の都市が一番上に、最大の都市が結果の一番下になります。state
およびcity
の並べ替えは、(Spring Data MongoDB が処理した) グループ ID フィールドに対して暗黙的に実行されることに注意してください。group
操作を再度使用して、中間結果をstate
でグループ化します。state
は再び暗黙的にグループ ID フィールドを参照することに注意してください。project
操作では、それぞれlast(…)
オペレーターとfirst(…)
オペレーターを呼び出して、最大都市と最小都市の名前と人口数を選択します。前の
group
操作からstate
フィールドを選択します。state
は再び暗黙的にグループ ID フィールドを参照することに注意してください。暗黙的に生成された ID が表示されることを望まないため、and(previousOperation()).exclude()
を使用して前の操作から ID を除外します。出力クラスにネストされたCity
構造体を設定したいため、ネストされたメソッドを使用して適切なサブドキュメントを出力する必要があります。sort
操作で、結果として得られるStateStats
のリストを状態名で昇順に並べ替えます。
入力コレクションの名前は、newAggregation
メソッドの最初のパラメーターとして渡される ZipInfo
クラスから派生することに注意してください。
集約 フレームワークの例 3
この例は、MongoDB Aggregation フレームワークドキュメントの人口 1,000 万人を超える状態 (英語) 例に基づいています。さまざまな MongoDB バージョンで安定した結果を生成するために、追加の並べ替えを追加しました。ここでは、集計フレームワークを使用して、人口が 1,000 万を超えるすべての状態を返したいと考えています。この例では、グループ化、並べ替え、一致 (フィルタリング) を示します。
class StateStats {
@Id String id;
String state;
@Field("totalPop") int totalPopulation;
}
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
TypedAggregation<ZipInfo> agg = newAggregation(ZipInfo.class,
group("state").sum("population").as("totalPop"),
sort(ASC, previousOperation(), "totalPop"),
match(where("totalPop").gte(10 * 1000 * 1000))
);
AggregationResults<StateStats> result = mongoTemplate.aggregate(agg, StateStats.class);
List<StateStats> stateStatsList = result.getMappedResults();
前述のリストでは次のアルゴリズムが使用されています。
入力コレクションを
state
フィールドごとにグループ化し、population
フィールドの合計を計算して、結果を新しいフィールド"totalPop"
に格納します。"totalPop"
フィールドに加えて、前のグループ操作の ID 参照によって中間結果を昇順に並べ替えます。Criteria
クエリを引数として受け入れるmatch
操作を使用して、中間結果をフィルター処理します。
入力コレクションの名前は、newAggregation
メソッドの最初のパラメーターとして渡される ZipInfo
クラスから派生することに注意してください。
集約 フレームワークの例 4
この例では、射影演算での単純な算術演算の使用を示します。
class Product {
String id;
String name;
double netPrice;
int spaceUnits;
}
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
TypedAggregation<Product> agg = newAggregation(Product.class,
project("name", "netPrice")
.and("netPrice").plus(1).as("netPricePlus1")
.and("netPrice").minus(1).as("netPriceMinus1")
.and("netPrice").multiply(1.19).as("grossPrice")
.and("netPrice").divide(2).as("netPriceDiv2")
.and("spaceUnits").mod(2).as("spaceUnitsMod2")
);
AggregationResults<Document> result = mongoTemplate.aggregate(agg, Document.class);
List<Document> resultList = result.getMappedResults();
入力コレクションの名前は、newAggregation
メソッドの最初のパラメーターとして渡される Product
クラスから派生することに注意してください。
集約 フレームワークの例 5
この例では、射影演算で SpEL 式から派生した単純な算術演算を使用する方法を示します。
class Product {
String id;
String name;
double netPrice;
int spaceUnits;
}
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
TypedAggregation<Product> agg = newAggregation(Product.class,
project("name", "netPrice")
.andExpression("netPrice + 1").as("netPricePlus1")
.andExpression("netPrice - 1").as("netPriceMinus1")
.andExpression("netPrice / 2").as("netPriceDiv2")
.andExpression("netPrice * 1.19").as("grossPrice")
.andExpression("spaceUnits % 2").as("spaceUnitsMod2")
.andExpression("(netPrice * 0.8 + 1.2) * 1.19").as("grossPriceIncludingDiscountAndCharge")
);
AggregationResults<Document> result = mongoTemplate.aggregate(agg, Document.class);
List<Document> resultList = result.getMappedResults();
集約 フレームワークの例 6
この例では、射影演算で SpEL 式から派生した複雑な算術演算を使用する方法を示します。
メモ: addExpression
メソッドに渡される追加パラメーターは、その位置に応じてインデクサー式を使用して参照できます。この例では、パラメーター配列の最初のパラメーターを [0]
で参照します。SpEL 式が MongoDB 集計フレームワーク式に変換されると、外部パラメーター式はそれぞれの値に置き換えられます。
class Product {
String id;
String name;
double netPrice;
int spaceUnits;
}
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
double shippingCosts = 1.2;
TypedAggregation<Product> agg = newAggregation(Product.class,
project("name", "netPrice")
.andExpression("(netPrice * (1-discountRate) + [0]) * (1+taxRate)", shippingCosts).as("salesPrice")
);
AggregationResults<Document> result = mongoTemplate.aggregate(agg, Document.class);
List<Document> resultList = result.getMappedResults();
SpEL 式内でドキュメントの他のフィールドを参照することもできることに注意してください。
集約 フレームワークの例 7
この例では、条件付き射影を使用します。$cond リファレンスドキュメント (英語) から派生したものです。
public class InventoryItem {
@Id int id;
String item;
String description;
int qty;
}
public class InventoryItemProjection {
@Id int id;
String item;
String description;
int qty;
int discount
}
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
TypedAggregation<InventoryItem> agg = newAggregation(InventoryItem.class,
project("item").and("discount")
.applyCondition(ConditionalOperator.newBuilder().when(Criteria.where("qty").gte(250))
.then(30)
.otherwise(20))
.and(ifNull("description", "Unspecified")).as("description")
);
AggregationResults<InventoryItemProjection> result = mongoTemplate.aggregate(agg, "inventory", InventoryItemProjection.class);
List<InventoryItemProjection> stateStatsList = result.getMappedResults();
このワンステップ集計では、inventory
コレクションによる射影操作が使用されます。250
以上の qty
を持つすべての在庫品目に対して条件付き操作を使用して、discount
フィールドを射影します。2 番目の条件付き射影が description
フィールドに対して実行されます。Unspecified
記述は、description
フィールドがないすべての項目、または null
記述がある項目に適用されます。
MongoDB 3.6 以降では、条件式を使用して射影からフィールドを除外することができます。
TypedAggregation<Book> agg = Aggregation.newAggregation(Book.class,
project("title")
.and(ConditionalOperators.when(ComparisonOperators.valueOf("author.middle") (1)
.equalToValue("")) (2)
.then("$$REMOVE") (3)
.otherwiseValueOf("author.middle") (4)
)
.as("author.middle"));
1 | フィールド author.middle の値が |
2 | 値が含まれていない |
3 | 次に、$$REMOVE (英語) を使用してフィールドを除外します。 |
4 | それ以外の場合は、フィールド値 author.middle を追加します。 |