Skip to content

Commit 9a13a3f

Browse files
committed
DATAMONGO-1553 - Polishing.
Convert spaces to tabs. Reorder methods. Add tests, nullability annotations, author tags and slightly rearrange documentation. Migrate tests to AssertJ. Extend year range in license headers. Original pull request: #519.
1 parent 7123f84 commit 9a13a3f

File tree

5 files changed

+168
-102
lines changed

5 files changed

+168
-102
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2017 the original author or authors.
2+
* Copyright 2013-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -358,6 +358,28 @@ public static SortOperation sort(Direction direction, String... fields) {
358358
return new SortOperation(Sort.by(direction, fields));
359359
}
360360

361+
/**
362+
* Creates a new {@link SortByCountOperation} given {@literal groupByField}.
363+
*
364+
* @param field must not be {@literal null} or empty.
365+
* @return
366+
* @since 2.1
367+
*/
368+
public static SortByCountOperation sortByCount(String field) {
369+
return new SortByCountOperation(field(field));
370+
}
371+
372+
/**
373+
* Creates a new {@link SortByCountOperation} given {@link AggregationExpression group and sort expression}.
374+
*
375+
* @param groupAndSortExpression must not be {@literal null}.
376+
* @return
377+
* @since 2.1
378+
*/
379+
public static SortByCountOperation sortByCount(AggregationExpression groupAndSortExpression) {
380+
return new SortByCountOperation(groupAndSortExpression);
381+
}
382+
361383
/**
362384
* Creates a new {@link SkipOperation} skipping the given number of elements.
363385
*
@@ -481,26 +503,6 @@ public static BucketAutoOperation bucketAuto(AggregationExpression groupByExpres
481503
return new BucketAutoOperation(groupByExpression, buckets);
482504
}
483505

484-
/**
485-
* Creates a new {@link SortByCountOperation} given {@literal groupByField}
486-
*
487-
* @param groupByField must not be {@literal null} or empty.
488-
* @return
489-
*/
490-
public static SortByCountOperation sortByCount(String groupByField) {
491-
return new SortByCountOperation(field(groupByField));
492-
}
493-
494-
/**
495-
* Creates a new {@link SortByCountOperation} given {@link AggregationExpression group-by expression}.
496-
*
497-
* @param groupByExpression must not be {@literal null}.
498-
* @return
499-
*/
500-
public static SortByCountOperation sortByCount(AggregationExpression groupByExpression) {
501-
return new SortByCountOperation(groupByExpression);
502-
}
503-
504506
/**
505507
* Creates a new {@link FacetOperation}.
506508
*
Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,57 +16,65 @@
1616
package org.springframework.data.mongodb.core.aggregation;
1717

1818
import org.bson.Document;
19+
import org.springframework.lang.Nullable;
1920
import org.springframework.util.Assert;
2021

2122
/**
22-
* Encapsulates the aggregation framework {@code $sortByCount}-operation. <br />
23-
*
24-
* SortByCount stage is typically used with {@link Aggregation} and {@code $facet}. Groups incoming documents
25-
* based on the value of a specified expression, then computes the count of documents in each distinct group. <br />
26-
*
23+
* Encapsulates the aggregation framework {@code $sortByCount}-operation.
24+
* <p/>
25+
* {@code $sortByCount} stage is typically used with {@link Aggregation} and {@code $facet}. Groups incoming documents
26+
* based on the value of a specified expression and computes the count of documents in each distinct group.
27+
* {@link SortByCountOperation} is equivalent to {@code { $group: { _id: <expression>, count: { $sum: 1 } } }, { $sort:
28+
* { count: -1 } }}.
29+
* <p/>
2730
* We recommend to use the static factory method {@link Aggregation#sortByCount(String)} instead of creating instances
2831
* of this class directly.
2932
*
30-
* @see <a href="https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/">https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/</a>
31-
* @author Jérôme GUYON
33+
* @see <a href=
34+
* "https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/">https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/</a>
35+
* @author Jérôme Guyon
36+
* @author Mark Paluch
37+
* @since 2.1
3238
*/
3339
public class SortByCountOperation implements AggregationOperation {
3440

35-
private final Field groupByField;
36-
private final AggregationExpression groupByExpression;
41+
private final @Nullable Field groupByField;
42+
private final @Nullable AggregationExpression groupByExpression;
3743

44+
/**
45+
* Creates a new {@link SortByCountOperation} given a {@link Field group-by field}.
46+
*
47+
* @param groupByField must not be {@literal null}.
48+
*/
49+
public SortByCountOperation(Field groupByField) {
3850

39-
/**
40-
* Creates a new {@link SortByCountOperation} given a {@link Field group-by field}.
41-
*
42-
* @param groupByField must not be {@literal null}.
43-
*/
44-
public SortByCountOperation(Field groupByField) {
51+
Assert.notNull(groupByField, "Group by field must not be null!");
4552

46-
Assert.notNull(groupByField, "Group by field must not be null!");
53+
this.groupByField = groupByField;
54+
this.groupByExpression = null;
55+
}
4756

48-
this.groupByField = groupByField;
49-
this.groupByExpression = null;
50-
}
57+
/**
58+
* Creates a new {@link SortByCountOperation} given a {@link AggregationExpression group-by expression}.
59+
*
60+
* @param groupByExpression must not be {@literal null}.
61+
*/
62+
public SortByCountOperation(AggregationExpression groupByExpression) {
5163

52-
/**
53-
* Creates a new {@link SortByCountOperation} given a {@link AggregationExpression group-by expression}.
54-
*
55-
* @param groupByExpression must not be {@literal null}.
56-
*/
57-
public SortByCountOperation(AggregationExpression groupByExpression) {
64+
Assert.notNull(groupByExpression, "Group by expression must not be null!");
5865

59-
Assert.notNull(groupByExpression, "Group by AggregationExpression must not be null!");
66+
this.groupByExpression = groupByExpression;
67+
this.groupByField = null;
68+
}
6069

61-
this.groupByExpression = groupByExpression;
62-
this.groupByField = null;
63-
}
70+
/*
71+
* (non-Javadoc)
72+
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
73+
*/
74+
@Override
75+
public Document toDocument(AggregationOperationContext context) {
6476

65-
@Override
66-
public Document toDocument(AggregationOperationContext context) {
67-
return new Document("$sortByCount",
68-
groupByExpression == null ? context.getReference(groupByField).toString()
69-
: groupByExpression.toDocument(context)
70-
);
71-
}
77+
return new Document("$sortByCount", groupByExpression == null ? context.getReference(groupByField).toString()
78+
: groupByExpression.toDocument(context));
79+
}
7280
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2017 the original author or authors.
2+
* Copyright 2016-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,15 +15,15 @@
1515
*/
1616
package org.springframework.data.mongodb.core.aggregation;
1717

18-
import static org.hamcrest.MatcherAssert.*;
18+
import static org.hamcrest.MatcherAssert.assertThat;
1919
import static org.hamcrest.Matchers.*;
2020
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
21+
import static org.springframework.data.mongodb.test.util.Assertions.assertThat;
2122

23+
import org.bson.Document;
2224
import org.junit.Test;
2325
import org.springframework.data.mongodb.core.query.Criteria;
2426

25-
import org.bson.Document;
26-
2727
/**
2828
* Unit tests for {@link FacetOperation}.
2929
*
@@ -34,29 +34,28 @@
3434
public class FacetOperationUnitTests {
3535

3636
@Test // DATAMONGO-1552
37-
public void shouldRenderCorrectly() throws Exception {
38-
39-
FacetOperation facetOperation = new FacetOperation()
40-
.and(match(Criteria.where("price").exists(true)), //
41-
bucket("price") //
42-
.withBoundaries(0, 150, 200, 300, 400) //
43-
.withDefaultBucket("Other") //
44-
.andOutputCount().as("count") //
45-
.andOutput("title").push().as("titles")) //
37+
public void shouldRenderCorrectly() {
38+
39+
FacetOperation facetOperation = new FacetOperation().and(match(Criteria.where("price").exists(true)), //
40+
bucket("price") //
41+
.withBoundaries(0, 150, 200, 300, 400) //
42+
.withDefaultBucket("Other") //
43+
.andOutputCount().as("count") //
44+
.andOutput("title").push().as("titles")) //
4645
.as("categorizedByPrice") //
4746
.and(bucketAuto("year", 5)).as("categorizedByYears");
4847

4948
Document agg = facetOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
5049

51-
assertThat(agg,
52-
is(Document.parse("{ $facet: { categorizedByPrice: [" + "{ $match: { price: { $exists: true } } }, "
50+
assertThat(agg)
51+
.isEqualTo(Document.parse("{ $facet: { categorizedByPrice: [" + "{ $match: { price: { $exists: true } } }, "
5352
+ "{ $bucket: { boundaries: [ 0, 150, 200, 300, 400 ], groupBy: \"$price\", default: \"Other\", "
5453
+ "output: { count: { $sum: 1 }, titles: { $push: \"$title\" } } } } ],"
55-
+ "categorizedByYears: [ { $bucketAuto: { buckets: 5, groupBy: \"$year\" } } ] } }")));
54+
+ "categorizedByYears: [ { $bucketAuto: { buckets: 5, groupBy: \"$year\" } } ] } }"));
5655
}
5756

5857
@Test // DATAMONGO-1552
59-
public void shouldRenderEmpty() throws Exception {
58+
public void shouldRenderEmpty() {
6059

6160
FacetOperation facetOperation = facet();
6261

@@ -66,7 +65,7 @@ public void shouldRenderEmpty() throws Exception {
6665
}
6766

6867
@Test(expected = IllegalArgumentException.class) // DATAMONGO-1552
69-
public void shouldRejectNonExistingFields() throws Exception {
68+
public void shouldRejectNonExistingFields() {
7069

7170
FacetOperation facetOperation = new FacetOperation()
7271
.and(project("price"), //
@@ -79,11 +78,11 @@ public void shouldRejectNonExistingFields() throws Exception {
7978

8079
Document agg = facetOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
8180

82-
assertThat(agg,
83-
is(Document.parse("{ $facet: { categorizedByPrice: [" + "{ $match: { price: { $exists: true } } }, "
81+
assertThat(agg)
82+
.isEqualTo(Document.parse("{ $facet: { categorizedByPrice: [" + "{ $match: { price: { $exists: true } } }, "
8483
+ "{ $bucket: {boundaries: [ 0, 150, 200, 300, 400 ], groupBy: \"$price\", default: \"Other\", "
8584
+ "output: { count: { $sum: 1 }, titles: { $push: \"$title\" } } } } ],"
86-
+ "categorizedByYears: [ { $bucketAuto: { buckets: 5, groupBy: \"$year\" } } ] } }")));
85+
+ "categorizedByYears: [ { $bucketAuto: { buckets: 5, groupBy: \"$year\" } } ] } }"));
8786
}
8887

8988
@Test // DATAMONGO-1552
@@ -97,22 +96,21 @@ public void shouldHonorProjectedFields() {
9796

9897
Document agg = facetOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
9998

100-
assertThat(agg,
101-
is(Document.parse("{ $facet: { categorizedByPrice: [" + "{ $project: { price: 1, name: \"$title\" } }, "
99+
assertThat(agg).isEqualTo(Document.parse("{ $facet: { categorizedByPrice: ["
100+
+ "{ $project: { price: 1, name: \"$title\" } }, "
102101
+ "{ $bucketAuto: { buckets: 5, groupBy: \"$price\", "
103-
+ "output: { titles: { $push: \"$name\" } } } } ] } }")));
102+
+ "output: { titles: { $push: \"$name\" } } } } ] } }"));
104103
}
105104

106105
@Test // DATAMONGO-1553
107106
public void shouldRenderSortByCountCorrectly() {
108107

109-
FacetOperation facetOperation = new FacetOperation()
110-
.and(sortByCount("country"))
108+
FacetOperation facetOperation = new FacetOperation() //
109+
.and(sortByCount("country")) //
111110
.as("categorizedByCountry");
112111

113112
Document agg = facetOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
114113

115-
assertThat(agg,
116-
is(Document.parse("{ $facet: { categorizedByCountry: [{ $sortByCount: \"$country\" } ] } }")));
114+
assertThat(agg).containsEntry("$facet.categorizedByCountry.[0].$sortByCount", "$country");
117115
}
118116
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mongodb.core.aggregation;
17+
18+
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
19+
import static org.springframework.data.mongodb.test.util.Assertions.*;
20+
21+
import java.util.Arrays;
22+
23+
import org.bson.Document;
24+
import org.junit.Test;
25+
26+
/**
27+
* Unit tests for {@link SortByCountOperation}.
28+
*
29+
* @author Mark Paluch
30+
*/
31+
public class SortByCountOperationUnitTests {
32+
33+
@Test // DATAMONGO-1553
34+
public void shouldRenderFieldCorrectly() {
35+
36+
SortByCountOperation operation = sortByCount("country");
37+
Document result = operation.toDocument(Aggregation.DEFAULT_CONTEXT);
38+
39+
assertThat(result).containsEntry("$sortByCount", "$country");
40+
}
41+
42+
@Test // DATAMONGO-1553
43+
public void shouldRenderExpressionCorrectly() {
44+
45+
SortByCountOperation operation = sortByCount(StringOperators.valueOf("foo").substring(5));
46+
Document result = operation.toDocument(Aggregation.DEFAULT_CONTEXT);
47+
48+
assertThat(result).containsEntry("$sortByCount.$substr", Arrays.asList("$foo", 5, -1));
49+
}
50+
}

0 commit comments

Comments
 (0)