最新的稳定版请使用 Spring Data MongoDB 4.3.1Spring中文文档

最新的稳定版请使用 Spring Data MongoDB 4.3.1Spring中文文档

Spring Data MongoDB 支持 2.2 版中引入的 MongoDB 聚合框架。Spring中文文档

有关详细信息,请参阅 MongoDB 的聚合框架和其他数据聚合工具的完整参考文档Spring中文文档

基本概念

Spring Data MongoDB 中的聚合框架支持基于以下关键抽象:、 和 。AggregationAggregationDefinitionAggregationResultsSpring中文文档

  • AggregationSpring中文文档

    an 表示 MongoDB 操作,并保存聚合管道指令的描述。聚合是通过调用类的相应静态工厂方法创建的,该方法采用一个列表和一个可选的输入类。AggregationaggregatenewAggregation(…)AggregationAggregateOperationSpring中文文档

    实际的聚合操作由 的方法 运行,该方法将所需的输出类作为参数。aggregateMongoTemplateSpring中文文档

  • TypedAggregationSpring中文文档

    A 和 一样,包含聚合管道的指令和对输入类型的引用,用于将域属性映射到实际文档字段。TypedAggregationAggregationSpring中文文档

    在运行时,会根据给定的输入类型检查字段引用,并考虑可能的注释。@FieldSpring中文文档

在 3.2 中更改,引用不存在的属性不再引发错误。要恢复以前的行为,请使用 选项。strictMappingAggregationOptionsSpring中文文档

  • AggregationDefinitionSpring中文文档

    an 表示 MongoDB 聚合管道操作,并描述在此聚合步骤中应执行的处理。尽管您可以手动创建一个 ,但我们建议使用该类提供的静态工厂方法来构造 .AggregationDefinitionAggregationDefinitionAggregateAggregateOperationSpring中文文档

  • AggregationResultsSpring中文文档

    AggregationResults是聚合操作结果的容器。它以映射对象的形式提供对原始聚合结果的访问,以及有关聚合的其他信息。DocumentSpring中文文档

    以下列表显示了将Spring Data MongoDB支持用于MongoDB聚合框架的规范示例:Spring中文文档

    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();

请注意,如果将输入类作为方法的第一个参数,则从此类派生输入集合的名称。否则,如果不指定输入类,则必须显式提供输入集合的名称。如果同时提供输入类和输入集合,则后者优先。newAggregationMongoTemplateSpring中文文档

支持的聚合操作和阶段

MongoDB聚合框架提供以下类型的聚合阶段和操作:Spring中文文档

不支持的聚合阶段(如 MongoDB Atlas 的 $search)可以通过实现任一 . 是通过提供管道阶段的 JSON 或表示形式来注册管道阶段的快捷方式。AggregationOperationAggregation.stageBsonSpring中文文档

Aggregation.stage("""
    { $search : {
        "near": {
          "path": "released",
          "origin": { "$date": { "$numberLong": "..." } } ,
          "pivot": 7
        }
      }
    }
""");

在撰写本文时,我们在 Spring Data MongoDB 中为以下聚合运算符提供支持:Spring中文文档

表 1.Spring Data MongoDB 当前支持的聚合运算符

设置聚合运算符Spring中文文档

setEquals, , , , , ,setIntersectionsetUnionsetDifferencesetIsSubsetanyElementTrueallElementsTrueSpring中文文档

组/累加器聚合算子Spring中文文档

addToSet, , , , , , , , , , , , , , , , , , (*), , , ,bottombottomNcovariancePopcovarianceSampexpMovingAvgfirstfirstNlastlastNmaxmaxNminminNavgpushsumtoptopNcountmedianpercentilestdDevPopstdDevSampSpring中文文档

算术聚合运算符Spring中文文档

abs、 (* 通过 )、 、 、acosacoshaddplusasinasinatanatan2atanhceilcoscoshderivativedivideexpfloorintegrallnloglog10modmultiplypowroundsqrtsubtractminussinsinhtantanhtruncSpring中文文档

字符串聚合运算符Spring中文文档

concat、、substrtoLowertoUpperstrcasecmpindexOfBytesindexOfCPregexFindregexFindAllregexMatchreplaceAllreplaceOnestrLenBytesstrLenCPsubstrCPtrimltrimrtimSpring中文文档

比较聚合运算符Spring中文文档

eq(* 通过)、、、、、isgtgteltlteneSpring中文文档

数组聚合运算符Spring中文文档

arrayElementAt、 、 、 、arrayToObjectconcatArraysfilterfirstinindexOfArrayisArraylastreverseArrayreducesizesortArrayslicezipSpring中文文档

文字运算符Spring中文文档

literalSpring中文文档

日期聚合运算符Spring中文文档

dateSubstract, , , , , , , , , , , , , , , , , , , , , ,dateTruncdayOfYeardayOfMonthdayOfWeekyearmonthweekhourminutesecondmilliseconddateAdddateDiffdateToStringdateFromStringdateFromPartsdateToPartsisoDayOfWeekisoWeekisoWeekYeartsIncrementtsSecondSpring中文文档

变量运算符Spring中文文档

mapSpring中文文档

条件聚合运算符Spring中文文档

cond, ,ifNullswitchSpring中文文档

类型聚合运算符Spring中文文档

typeSpring中文文档

转换聚合运算符Spring中文文档

convert, , , , , , , , ,degreesToRadianstoBooltoDatetoDecimaltoDoubletoInttoLongtoObjectIdtoStringSpring中文文档

对象聚合运算符Spring中文文档

objectToArray, , ,mergeObjectsgetFieldsetFieldSpring中文文档

脚本聚合运算符Spring中文文档

function,accumulatorSpring中文文档

* 该操作由 Spring Data MongoDB 映射或添加。Spring中文文档

请注意,Spring Data MongoDB 目前不支持此处未列出的聚合操作。比较聚合运算符表示为表达式。CriteriaSpring中文文档

不支持的聚合阶段(如 MongoDB Atlas 的 $search)可以通过实现任一 . 是通过提供管道阶段的 JSON 或表示形式来注册管道阶段的快捷方式。AggregationOperationAggregation.stageBsonSpring中文文档

Aggregation.stage("""
    { $search : {
        "near": {
          "path": "released",
          "origin": { "$date": { "$numberLong": "..." } } ,
          "pivot": 7
        }
      }
    }
""");
表 1.Spring Data MongoDB 当前支持的聚合运算符

设置聚合运算符Spring中文文档

setEquals, , , , , ,setIntersectionsetUnionsetDifferencesetIsSubsetanyElementTrueallElementsTrueSpring中文文档

组/累加器聚合算子Spring中文文档

addToSet, , , , , , , , , , , , , , , , , , (*), , , ,bottombottomNcovariancePopcovarianceSampexpMovingAvgfirstfirstNlastlastNmaxmaxNminminNavgpushsumtoptopNcountmedianpercentilestdDevPopstdDevSampSpring中文文档

算术聚合运算符Spring中文文档

abs、 (* 通过 )、 、 、acosacoshaddplusasinasinatanatan2atanhceilcoscoshderivativedivideexpfloorintegrallnloglog10modmultiplypowroundsqrtsubtractminussinsinhtantanhtruncSpring中文文档

字符串聚合运算符Spring中文文档

concat、、substrtoLowertoUpperstrcasecmpindexOfBytesindexOfCPregexFindregexFindAllregexMatchreplaceAllreplaceOnestrLenBytesstrLenCPsubstrCPtrimltrimrtimSpring中文文档

比较聚合运算符Spring中文文档

eq(* 通过)、、、、、isgtgteltlteneSpring中文文档

数组聚合运算符Spring中文文档

arrayElementAt、 、 、 、arrayToObjectconcatArraysfilterfirstinindexOfArrayisArraylastreverseArrayreducesizesortArrayslicezipSpring中文文档

文字运算符Spring中文文档

literalSpring中文文档

日期聚合运算符Spring中文文档

dateSubstract, , , , , , , , , , , , , , , , , , , , , ,dateTruncdayOfYeardayOfMonthdayOfWeekyearmonthweekhourminutesecondmilliseconddateAdddateDiffdateToStringdateFromStringdateFromPartsdateToPartsisoDayOfWeekisoWeekisoWeekYeartsIncrementtsSecondSpring中文文档

变量运算符Spring中文文档

mapSpring中文文档

条件聚合运算符Spring中文文档

cond, ,ifNullswitchSpring中文文档

类型聚合运算符Spring中文文档

typeSpring中文文档

转换聚合运算符Spring中文文档

convert, , , , , , , , ,degreesToRadianstoBooltoDatetoDecimaltoDoubletoInttoLongtoObjectIdtoStringSpring中文文档

对象聚合运算符Spring中文文档

objectToArray, , ,mergeObjectsgetFieldsetFieldSpring中文文档

脚本聚合运算符Spring中文文档

function,accumulatorSpring中文文档

投影表达式

投影表达式用于定义作为特定聚合步骤结果的字段。投影表达式可以通过类的方法定义,通过传递对象列表或聚合框架对象。可以使用该方法通过 Fluent API 使用其他字段扩展投影,并使用该方法进行别名化。 请注意,您还可以使用聚合框架的静态工厂方法来定义具有别名的字段,然后可以使用该方法构造新实例。在后续聚合阶段中对投影字段的引用仅对包含字段的字段名称或其别名(包括新定义的字段及其别名)有效。投影中未包含的字段无法在以后的聚合阶段中引用。以下列表显示了投影表达式的示例:projectAggregationStringFieldsand(String)as(String)Fields.fieldFieldsSpring中文文档

例 1.投影表达式示例
// 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")
例 2.使用投影和排序的多级聚合
// 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")

有关项目操作的更多示例,请参阅该课程。请注意,有关投影表达式的更多详细信息可以在MongoDB聚合框架参考文档的相应部分中找到。AggregationTestsSpring中文文档

分面分类

从版本 3.4 开始,MongoDB 支持使用聚合框架进行分面分类。分面分类使用语义类别(常规类别或特定主题类别)进行组合以创建完整的分类条目。流经聚合管道的文档被分类到存储桶中。多方面分类支持对同一组输入文档进行各种聚合,而无需多次检索输入文档。Spring中文文档

存储桶操作根据指定的表达式和存储桶边界将传入的文档分类为组,称为存储桶。存储桶操作需要分组字段或分组表达式。可以使用类的 and 方法来定义它们。 并且可以公开基于输入文档的聚合表达式的累积。您可以使用这些方法和方法,通过 Fluent API 使用其他参数扩展存储桶操作。您可以使用该方法对操作进行别名化名。每个存储桶在输出中都表示为一个文档。bucket()bucketAuto()AggregateBucketOperationBucketAutoOperationwith…()andOutput(String)as(String)Spring中文文档

BucketOperation采用一组定义的边界,将传入的文档分组到这些类别中。需要对边界进行排序。以下列表显示了存储桶操作的一些示例:Spring中文文档

例 3.铲斗操作示例
// 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确定边界,以尝试将文档均匀地分布到指定数量的存储桶中。 (可选)采用一个粒度值,该值指定要使用的首选数系列,以确保计算的边界边以首选整数或 10 的幂结束。以下列表显示了存储桶操作的示例:BucketAutoOperationSpring中文文档

例 4.铲斗操作示例
// 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");

要在存储桶中创建输出字段,存储桶操作可以使用 through 和 SpEL 表达式AggregationExpressionandOutput()andOutputExpression()Spring中文文档

请注意,有关存储桶表达式的更多详细信息,请参阅 MongoDB 聚合框架参考文档的 $bucket 部分$bucketAuto部分Spring中文文档

多方面聚合

多个聚合管道可用于创建多方面聚合,以表征单个聚合阶段中跨多个维度(或多个方面)的数据。多方面聚合提供多个筛选器和分类来指导数据浏览和分析。分面的一种常见实现是,有多少在线零售商通过对产品价格、制造商、尺寸和其他因素应用过滤器来缩小搜索结果范围。Spring中文文档

可以使用类的方法定义 a。您可以使用该方法使用多个聚合管道对其进行自定义。每个子管道在输出文档中都有自己的字段,其结果存储为文档数组。FacetOperationfacet()Aggregationand()Spring中文文档

子管道可以在分组之前投影和筛选输入文档。常见用例包括在分类之前提取日期部分或计算。以下列表显示了分面操作示例:Spring中文文档

例 5.分面操作示例
// 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 聚合框架参考文档的$facet部分找到。Spring中文文档

按计数排序

按计数排序 操作 根据指定表达式的值对传入的文档进行分组,计算每个不同组中的文档计数,并按计数对结果进行排序。它提供了一个方便的快捷方式,用于在使用分面分类时应用排序。按计数排序操作需要分组字段或分组表达式。以下列表显示了一个按计数排序的示例:Spring中文文档

例 6.按计数排序示例
// generates { $sortByCount: "$country" }
sortByCount("country");

按计数排序操作等效于以下 BSON(二进制 JSON):Spring中文文档

{ $group: { _id: <expression>, count: { $sum: 1 } } },
{ $sort: { count: -1 } }

投影表达式中的 Spring 表达式支持

我们支持通过 和 类的方法在投影表达式中使用 SpEL 表达式。此功能允许您将所需的表达式定义为 SpEL 表达式。在运行查询时,SpEL 表达式将转换为相应的 MongoDB 投影表达式部分。这种安排使表达复杂的计算变得更加容易。andExpressionProjectionOperationBucketOperationSpring中文文档

使用 SpEL 表达式的复杂计算

请考虑以下 SpEL 表达式:Spring中文文档

1 + (q + 1) / (q - 1)

前面的表达式将转换为以下投影表达式部分:Spring中文文档

{ "$add" : [ 1, {
    "$divide" : [ {
        "$add":["$q", 1]}, {
        "$subtract":[ "$q", 1]}
    ]
}]}

您可以在聚合框架示例 5聚合框架示例 6 中查看更多上下文中的示例。 您可以在 中找到更多受支持的 SpEL 表达式构造的使用示例。SpelExpressionTransformerUnitTestsSpring中文文档

支持的 SpEL 转换
SpEL表达 Mongo 表达式部分

a == bSpring中文文档

{ $eq : [$a, $b] }Spring中文文档

a != bSpring中文文档

{ $ne : [$a , $b] }Spring中文文档

A > BSpring中文文档

{ $gt : [$a, $b] }Spring中文文档

a >= bSpring中文文档

{ $gte : [$a, $b] }Spring中文文档

A < BSpring中文文档

{ $lt : [$a, $b] }Spring中文文档

A ⇐ BSpring中文文档

{ $lte : [$a, $b] }Spring中文文档

甲+乙Spring中文文档

{ $add : [$a, $b] }Spring中文文档

甲 - 乙Spring中文文档

{ $subtract : [$a, $b] }Spring中文文档

一个 * bSpring中文文档

{ $multiply : [$a, $b] }Spring中文文档

一个 / bSpring中文文档

{ $divide : [$a, $b] }Spring中文文档

a^bSpring中文文档

{ $pow : [$a, $b] }Spring中文文档

a % bSpring中文文档

{ $mod : [$a, $b] }Spring中文文档

A && BSpring中文文档

{ $and : [$a, $b] }Spring中文文档

一个 ||bSpring中文文档

{ $or : [$a, $b] }Spring中文文档

!一个Spring中文文档

{ $not : [$a] }Spring中文文档

除了上表中显示的转换之外,还可以使用标准的 SpEL 操作,例如(例如)通过数组的名称创建数组和引用表达式(后跟括号中的参数)。下面的示例演示如何以这种方式创建数组:newSpring中文文档

// { $setEquals : [$a, [5, 8, 13] ] }
.andExpression("setEquals(a, new int[]{5, 8, 13})");

聚合框架示例

本节中的示例演示了 MongoDB 聚合框架与 Spring Data MongoDB 的使用模式。Spring中文文档

聚合框架示例 1

在这个介绍性示例中,我们希望聚合一个标签列表,以从 MongoDB 集合(称为 )中获取特定标签的出现次数,并按出现次数降序排序。此示例演示了分组、排序、投影(选择)和展开(结果拆分)的用法。tagsSpring中文文档

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();

上面的清单使用以下算法:Spring中文文档

  1. 使用静态工厂方法创建新的聚合,我们将聚合操作列表传递给该方法。这些聚合操作定义了我们的 .newAggregationAggregationSpring中文文档

  2. 使用该操作从输入集合中选择字段(字符串数组)。projecttagsSpring中文文档

  3. 使用该操作为数组中的每个标记生成一个新文档。unwindtagsSpring中文文档

  4. 使用该操作为我们聚合出现次数的每个值定义一个组(通过使用聚合运算符并将结果收集到名为 的新字段中)。grouptagscountnSpring中文文档

  5. 选择该字段,并为从上一个组操作(因此调用 )生成的 ID 字段创建一个别名,名称为 。npreviousOperation()tagSpring中文文档

  6. 使用该操作按出现次数降序对生成的标签列表进行排序。sortSpring中文文档

  7. 调用该方法以让 MongoDB 执行实际的聚合操作,并将 created 作为参数。aggregateMongoTemplateAggregationSpring中文文档

请注意,输入集合被显式指定为 Method 的参数。如果未显式指定输入集合的名称,则该名称派生自作为第一个参数传递给方法的输入类。tagsaggregatenewAggreationSpring中文文档

聚合框架示例 2

此示例基于 MongoDB 聚合框架文档中的“按州划分的最大和最小城市”示例。我们添加了额外的排序功能,以在不同的 MongoDB 版本下生成稳定的结果。在这里,我们希望使用聚合框架返回每个州按人口划分的最小和最大城市。此示例演示分组、排序和投影(选择)。Spring中文文档

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);

请注意,该类映射给定输入集合的结构。该类以所需的输出格式定义结构。ZipInfoZipInfoStatsSpring中文文档

上述列表使用以下算法:Spring中文文档

  1. 使用该操作从输入集合中定义组。分组条件是 和 字段的组合,它构成了组的 ID 结构。我们使用运算符从分组元素中聚合属性的值,并将结果保存在字段中。groupstatecitypopulationsumpopSpring中文文档

  2. 使用该操作按 和 字段按升序对中间结果进行排序,使最小的城市位于结果的顶部,最大的城市位于结果的底部。请注意,对 和 的排序是针对组 ID 字段(Spring Data MongoDB 处理的)隐式执行的。sortpopstatecitystatecitySpring中文文档

  3. 再次使用操作将中间结果按 分组。请注意,这再次隐式引用组 ID 字段。我们选择最大和最小城市的名称和人口数量,并在操作中分别呼叫 和 运营商。groupstatestatelast(…)first(…​)projectSpring中文文档

  4. 从上一个操作中选择字段。请注意,这再次隐式引用组 ID 字段。由于我们不希望出现隐式生成的 ID,因此我们使用 从前面的操作中排除该 ID。由于我们希望在输出类中填充嵌套结构,因此必须使用嵌套方法发出相应的子文档。stategroupstateand(previousOperation()).exclude()CitySpring中文文档

  5. 在操作中按其状态名称升序对结果列表进行排序。StateStatssortSpring中文文档

请注意,我们从作为第一个参数传递给方法的类派生输入集合的名称。ZipInfonewAggregationSpring中文文档

聚合框架示例 3

此示例基于 MongoDB 聚合框架文档中的“人口超过 1000 万的州”示例。我们添加了额外的排序功能,以在不同的 MongoDB 版本下生成稳定的结果。在这里,我们希望使用聚合框架返回人口超过 1000 万的所有州。此示例演示了分组、排序和匹配(筛选)。Spring中文文档

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();

上述列表使用以下算法:Spring中文文档

  1. 按字段对输入集合进行分组,并计算字段的总和,并将结果存储在新字段中。statepopulation"totalPop"Spring中文文档

  2. 除按升序排列的字段外,还按上一个组操作的 id-reference 对中间结果进行排序。"totalPop"Spring中文文档

  3. 使用接受查询作为参数的操作筛选中间结果。matchCriteriaSpring中文文档

请注意,我们从作为第一个参数传递给方法的类中派生输入集合的名称。ZipInfonewAggregationSpring中文文档

聚合框架示例 4

此示例演示了在投影运算中使用简单的算术运算。Spring中文文档

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();

请注意,我们从作为第一个参数传递给方法的类中派生输入集合的名称。ProductnewAggregationSpring中文文档

聚合框架示例 5

此示例演示了在投影操作中使用派生自 SpEL 表达式的简单算术运算。Spring中文文档

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 表达式的复杂算术运算。Spring中文文档

注意:传递给方法的其他参数可以根据其位置使用索引器表达式进行引用。在此示例中,我们使用 .当 SpEL 表达式转换为 MongoDB 聚合框架表达式时,外部参数表达式将替换为其各自的值。addExpression[0]Spring中文文档

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 表达式中引用文档的其他字段。Spring中文文档

聚合框架示例 7

此示例使用条件投影。它源自$cond参考文档Spring中文文档

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();

此一步聚合对集合使用投影操作。我们通过对 大于或等于 的所有库存物料使用条件运算来投影字段。对字段执行第二个条件投影。我们将描述应用于所有没有字段的项目或有描述的项目。inventorydiscountqty250descriptionUnspecifieddescriptionnullSpring中文文档

从MongoDB 3.6开始,可以使用条件表达式从投影中排除字段。Spring中文文档

例 7.条件聚合投影
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
SpEL表达 Mongo 表达式部分

a == bSpring中文文档

{ $eq : [$a, $b] }Spring中文文档

a != bSpring中文文档

{ $ne : [$a , $b] }Spring中文文档

A > BSpring中文文档

{ $gt : [$a, $b] }Spring中文文档

a >= bSpring中文文档

{ $gte : [$a, $b] }Spring中文文档

A < BSpring中文文档

{ $lt : [$a, $b] }Spring中文文档

A ⇐ BSpring中文文档

{ $lte : [$a, $b] }Spring中文文档

甲+乙Spring中文文档

{ $add : [$a, $b] }Spring中文文档

甲 - 乙Spring中文文档

{ $subtract : [$a, $b] }Spring中文文档

一个 * bSpring中文文档

{ $multiply : [$a, $b] }Spring中文文档

一个 / bSpring中文文档

{ $divide : [$a, $b] }Spring中文文档

a^bSpring中文文档

{ $pow : [$a, $b] }Spring中文文档

a % bSpring中文文档

{ $mod : [$a, $b] }Spring中文文档

A && BSpring中文文档

{ $and : [$a, $b] }Spring中文文档

一个 ||bSpring中文文档

{ $or : [$a, $b] }Spring中文文档

!一个Spring中文文档

{ $not : [$a] }Spring中文文档

1 如果字段的值author.middle
2 不包含值,
3 然后使用 $$REMOVE 排除该字段。
4 否则,请添加 的字段值。author.middle