From f3f537c1a6f374ba6674b9ee419fc8f5970abce9 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Mon, 5 Aug 2013 17:20:37 +0200 Subject: [PATCH] DATAMONGO-586 - Adjusted examples in reference documentation. Modified formatting and moved the detailed descriptions below the example code. Added example for arithmetic operations in projection operations. --- src/docbkx/reference/mongodb.xml | 378 ++++++++++++++++++------------- 1 file changed, 226 insertions(+), 152 deletions(-) diff --git a/src/docbkx/reference/mongodb.xml b/src/docbkx/reference/mongodb.xml index ef11b7235..922c9cf21 100644 --- a/src/docbkx/reference/mongodb.xml +++ b/src/docbkx/reference/mongodb.xml @@ -2214,17 +2214,16 @@ GroupByResults<XObject> results = mongoTemplate.group(where("x").gt(0), for the MongoDB Aggregation Framework looks as follows: 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(); -… + Note that if you provide an input class as the first parameter to the newAggregation method the @@ -2321,57 +2320,29 @@ List<OutputType> mappedResult = results.getMappedResults(); *) The operation is mapped or added by Spring Data MongoDB. -
- Aggregation Framework Example 1 - - In this introductory example we want to aggregate a list of tags - to get the occurence count of a particular tag from a MongoDB collection - called "tags" sorted by the occurence count in descending - order. This example demonstrates the usage of grouping, sorting, - projections (selection) and unwinding (result splitting). - - In order to do this we first create a new aggregation via the - newAggregation static factory method to which - we pass a list of aggregation operations. These aggregate operations - form the aggregation pipeline of our - Aggregation. - - As a first step we select the "tags" field (which is - an array of strings) from the input collection with the - project operation. - - In a second step we use the unwind - operation to generate a new document for each tag within the - "tags" array. - - In the third step we use the group - operation to define a group for each "tags"-value for which - we aggregate the occurence count via the count - aggregation operator and collect the result in a new field called - "n". - - As a forth step we select the field "n" and create an - alias for the id-field generated from the previous group operation - (hence the call to previousOperation()) with the name - "tag". - - Finally as the fifth step we sort the resulting list of tags by - their occurence count in descending order via the - sort operation. - - In order to let MongoDB perform the acutal aggregation operation - we call the aggregate Method on the - MongoTemplate with the created Aggregation as an - argument. - - class TagCount { - private String tag; - private int n; -… -} +
+ Aggregation Framework Examples + + The follwing examples demonstrate the usage patterns for the + MongoDB Aggregation Framework with Spring Data MongoDB. + + + Aggregation Framework Example 1 + + In this introductory example we want to aggregate a list of tags + to get the occurence count of a particular tag from a MongoDB + collection called "tags" sorted by the occurence count in + descending order. This example demonstrates the usage of grouping, + sorting, projections (selection) and unwinding (result + splitting). + + class TagCount { + String tag; + int n; +} + + import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; -… Aggregation agg = newAggregation( project("tags"), unwind("tags"), @@ -2381,83 +2352,88 @@ Aggregation agg = newAggregation( ); AggregationResults<TagCount> results = mongoTemplate.aggregate(agg, "tags", TagCount.class); -List<TagCount> tagCount = results.getMappedResults(); -… +List<TagCount> tagCount = results.getMappedResults(); + + + + + In order to do this we first create a new aggregation via the + newAggregation static factory method to + which we pass a list of aggregation operations. These aggregate + operations define the aggregation pipeline of our + Aggregation. + + + + As a second step we select the "tags" field + (which is an array of strings) from the input collection with the + project operation. + + + + In a third step we use the unwind + operation to generate a new document for each tag within the + "tags" array. + + + + In the forth step we use the group + operation to define a group for each "tags"-value for + which we aggregate the occurence count via the + count aggregation operator and collect the + result in a new field called "n". + + + + As a fifth step we select the field "n" and + create an alias for the id-field generated from the previous group + operation (hence the call to previousOperation()) with + the name "tag". + + + + As the sixth step we sort the resulting list of tags by their + occurence count in descending order via the + sort operation. + + + + Finally we call the aggregate Method + on the MongoTemplate in order to let MongoDB perform the acutal + aggregation operation with the created + Aggregation as an argument. + + Note that the input collection is explicitly specified as the "tags" parameter to the aggregate Method. If the name of the input collection is not specified explicitly, it is derived from the input-class passed as first parameter to the newAggreation Method. -
-
- Aggregation Framework Example 2 - - This example is based on the Largest - and Smallest Cities by State example from the MongoDB - Aggregation Framework documentation. We added additional sorting to - produce stable results with different MongoDB versions. Here we want to - return the smallest and largest cities by population for each state, - using the aggregation framework. This example demonstrates the usage of - grouping, sorting and projections (selection). - - The class ZipInfo maps the structure of the - given input-collection. The class ZipInfoStats - defines the structure in the desired output format. - - As a first step we use the group - operation to define a group from the input-collection. The grouping - criteria is the combination of the fields "state" and - "city" which forms the id structure of the group. We - aggregate the value of the "population" field from the - grouped elements with by using the sum operator - saving the result in the field "pop". - - In a second step we use the sort - operation to sort the intermediate-result by the fields - "pop", "state" and "city" in - ascending order, such that the smallest city is at the top and the - biggest city is at the bottom of the result. Note that the sorting on - "state" and "city" is implicitly performed against the - group id fields which Spring Data MongoDB took care of. - - In the third step we use a group - operation again to group the intermediate result by - "state". Note that "state" again implicitly - references an group-id field. We select the name and the population - count of the biggest and smallest city with calls to the - last(…) and first(...) operator respectively - via the project operation. - - As the forth step we select the "state" field from - the previous group operation. Note that - "state" again implicitly references an group-id field. As - we do not want an implict generated id to appear, we exclude the id from - the previous operation via - and(previousOperation()).exclude(). As we want to populate - the nested City structures in our output-class - accordingly we have to emit appropriate sub-documents with the nested - method. - - Finally as the fifth step we sort the resulting list of - StateStats by their state name in ascending order - via the sort operation. - - class ZipInfo { + + Aggregation Framework Example 2 + + This example is based on the Largest + and Smallest Cities by State example from the MongoDB + Aggregation Framework documentation. We added additional sorting to + produce stable results with different MongoDB versions. Here we want + to return the smallest and largest cities by population for each + state, using the aggregation framework. This example demonstrates the + usage of grouping, sorting and projections (selection). + + class ZipInfo { String id; String city; String state; @Field("pop") int population; @Field("loc") double[] location; -… } class City { String name; int population; -… } class ZipInfoStats { @@ -2465,13 +2441,13 @@ class ZipInfoStats { String state; City biggestCity; City smallestCity; -… -} +} + + import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; -… TypedAggregation<ZipInfo> aggregation = newAggregation(ZipInfo.class, - group("state", "city").sum("population").as("pop"), + group("state", "city") + .sum("population").as("pop"), sort(ASC, "pop", "state", "city"), group("state") .last("city").as("biggestCity") @@ -2480,55 +2456,100 @@ TypedAggregation<ZipInfo> aggregation = newAggregation(ZipInfo.class, .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")), + .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); -… + - Note that we derive the name of the input-collection from the - ZipInfo-class passed as first parameter to the - newAggregation-Method. -
+ + + The class ZipInfo maps the structure of + the given input-collection. The class + ZipInfoStats defines the structure in the + desired output format. + + + + As a first step we use the group + operation to define a group from the input-collection. The grouping + criteria is the combination of the fields "state" and + "city" which forms the id structure of the group. We + aggregate the value of the "population" property from + the grouped elements with by using the sum + operator saving the result in the field "pop". + + + + In a second step we use the sort + operation to sort the intermediate-result by the fields + "pop", "state" and "city" in + ascending order, such that the smallest city is at the top and the + biggest city is at the bottom of the result. Note that the sorting + on "state" and "city" is implicitly performed against + the group id fields which Spring Data MongoDB took care of. + + + + In the third step we use a group + operation again to group the intermediate result by + "state". Note that "state" again + implicitly references an group-id field. We select the name and the + population count of the biggest and smallest city with calls to the + last(…) and first(...) operator + respectively via the project + operation. + -
- Aggregation Framework Example 3 + + As the forth step we select the "state" field + from the previous group operation. Note + that "state" again implicitly references an group-id + field. As we do not want an implict generated id to appear, we + exclude the id from the previous operation via + and(previousOperation()).exclude(). As we want to + populate the nested City structures in our + output-class accordingly we have to emit appropriate sub-documents + with the nested method. + - This example is based on the States - with Populations Over 10 Million example from the MongoDB - Aggregation Framework documentation. We added additional sorting to - produce stable results with different MongoDB versions. Here we want to - return all states with a population greater than 10 million, using the - aggregation framework. This example demonstrates the usage of grouping, - sorting and matching (filtering). + + Finally as the fifth step we sort the resulting list of + StateStats by their state name in ascending + order via the sort operation. + + - In the first step we group the input collection by the - "state" field and calculate the sum of the - "population" field and store the result in the new field - "totalPop". + Note that we derive the name of the input-collection from the + ZipInfo-class passed as first parameter to the + newAggregation-Method. - As a second step we sort the intermediate result by the - id-reference of the previous group operation in addition to the - "totalPop" field in ascending order. + + Aggregation Framework Example 3 - Finally in the third step we filter the intermediate result by - using a match operation which accepts a - Criteria query as an argument. + This example is based on the States + with Populations Over 10 Million example from the MongoDB + Aggregation Framework documentation. We added additional sorting to + produce stable results with different MongoDB versions. Here we want + to return all states with a population greater than 10 million, using + the aggregation framework. This example demonstrates the usage of + grouping, sorting and matching (filtering). - class StateStats { + class StateStats { @Id String id; String state; @Field("totalPop") int totalPopulation; -… -} +} + + import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; -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"), @@ -2536,12 +2557,65 @@ TypedAggregation<ZipInfo> agg = newAggregation(ZipInfo.class, ); AggregationResults<StateStats> result = mongoTemplate.aggregate(agg, StateStats.class); -List<StateStats> stateStatsList = result.getMappedResults(); -… +List<StateStats> stateStatsList = result.getMappedResults(); + + + + + As a first step we group the input collection by the + "state" field and calculate the sum of the + "population" field and store the result in the new + field "totalPop". + + + + In the second step we sort the intermediate result by the + id-reference of the previous group operation in addition to the + "totalPop" field in ascending order. + + + + Finally in the third step we filter the intermediate result by + using a match operation which accepts a + Criteria query as an argument. + + Note that we derive the name of the input-collection from the ZipInfo-class passed as first parameter to the newAggregation-Method. + + + Aggregation Framework Example 4 + + This example demonstrates the use of arithmetic operations in + the projection operation. + + 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<DBObject> result = mongoTemplate.aggregate(agg, DBObject.class); +List<DBObject> resultList = result.getMappedResults(); + + + Note that we derive the name of the input-collection from the + Product-class passed as first parameter to the + newAggregation-Method.