Skip to content

Commit 5c4d5bd

Browse files
alessiofachechichristophstrobl
authored andcommitted
DATAMONGO-1326 - Add support for $lookup to aggregation.
Original Pull Request: #344 CLA: 164120160221125037 (Alessio Fachechi)
1 parent 7e23956 commit 5c4d5bd

File tree

5 files changed

+249
-34
lines changed

5 files changed

+249
-34
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2013 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+
/**
19+
* {@link AggregationOperation} that exposes <b>additional</b> {@link ExposedFields} that can be used for later
20+
* aggregation pipeline {@code AggregationOperation}s, e.g. lookup operation produces a field which has to be added to
21+
* the current ones.
22+
*
23+
* @author Alessio Fachechi
24+
*/
25+
public interface AdditionalFieldsExposingAggregationOperation extends FieldsExposingAggregationOperation {
26+
27+
}

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

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@
3737
/**
3838
* An {@code Aggregation} is a representation of a list of aggregation steps to be performed by the MongoDB Aggregation
3939
* Framework.
40-
*
40+
*
4141
* @author Tobias Trelle
4242
* @author Thomas Darimont
4343
* @author Oliver Gierke
44+
* @author Alessio Fachechi
4445
* @since 1.3
4546
*/
4647
public class Aggregation {
@@ -65,7 +66,7 @@ public class Aggregation {
6566

6667
/**
6768
* Creates a new {@link Aggregation} from the given {@link AggregationOperation}s.
68-
*
69+
*
6970
* @param operations must not be {@literal null} or empty.
7071
*/
7172
public static Aggregation newAggregation(List<? extends AggregationOperation> operations) {
@@ -74,7 +75,7 @@ public static Aggregation newAggregation(List<? extends AggregationOperation> op
7475

7576
/**
7677
* Creates a new {@link Aggregation} from the given {@link AggregationOperation}s.
77-
*
78+
*
7879
* @param operations must not be {@literal null} or empty.
7980
*/
8081
public static Aggregation newAggregation(AggregationOperation... operations) {
@@ -84,7 +85,7 @@ public static Aggregation newAggregation(AggregationOperation... operations) {
8485
/**
8586
* Returns a copy of this {@link Aggregation} with the given {@link AggregationOptions} set. Note that options are
8687
* supported in MongoDB version 2.6+.
87-
*
88+
*
8889
* @param options must not be {@literal null}.
8990
* @return
9091
* @since 1.6
@@ -97,7 +98,7 @@ public Aggregation withOptions(AggregationOptions options) {
9798

9899
/**
99100
* Creates a new {@link TypedAggregation} for the given type and {@link AggregationOperation}s.
100-
*
101+
*
101102
* @param type must not be {@literal null}.
102103
* @param operations must not be {@literal null} or empty.
103104
*/
@@ -107,7 +108,7 @@ public static <T> TypedAggregation<T> newAggregation(Class<T> type, List<? exten
107108

108109
/**
109110
* Creates a new {@link TypedAggregation} for the given type and {@link AggregationOperation}s.
110-
*
111+
*
111112
* @param type must not be {@literal null}.
112113
* @param operations must not be {@literal null} or empty.
113114
*/
@@ -117,7 +118,7 @@ public static <T> TypedAggregation<T> newAggregation(Class<T> type, AggregationO
117118

118119
/**
119120
* Creates a new {@link Aggregation} from the given {@link AggregationOperation}s.
120-
*
121+
*
121122
* @param aggregationOperations must not be {@literal null} or empty.
122123
*/
123124
protected Aggregation(AggregationOperation... aggregationOperations) {
@@ -137,7 +138,7 @@ protected static List<AggregationOperation> asAggregationList(AggregationOperati
137138

138139
/**
139140
* Creates a new {@link Aggregation} from the given {@link AggregationOperation}s.
140-
*
141+
*
141142
* @param aggregationOperations must not be {@literal null} or empty.
142143
*/
143144
protected Aggregation(List<AggregationOperation> aggregationOperations) {
@@ -146,7 +147,7 @@ protected Aggregation(List<AggregationOperation> aggregationOperations) {
146147

147148
/**
148149
* Creates a new {@link Aggregation} from the given {@link AggregationOperation}s.
149-
*
150+
*
150151
* @param aggregationOperations must not be {@literal null} or empty.
151152
* @param options must not be {@literal null} or empty.
152153
*/
@@ -162,7 +163,7 @@ protected Aggregation(List<AggregationOperation> aggregationOperations, Aggregat
162163

163164
/**
164165
* A pointer to the previous {@link AggregationOperation}.
165-
*
166+
*
166167
* @return
167168
*/
168169
public static String previousOperation() {
@@ -171,7 +172,7 @@ public static String previousOperation() {
171172

172173
/**
173174
* Creates a new {@link ProjectionOperation} including the given fields.
174-
*
175+
*
175176
* @param fields must not be {@literal null}.
176177
* @return
177178
*/
@@ -181,7 +182,7 @@ public static ProjectionOperation project(String... fields) {
181182

182183
/**
183184
* Creates a new {@link ProjectionOperation} includeing the given {@link Fields}.
184-
*
185+
*
185186
* @param fields must not be {@literal null}.
186187
* @return
187188
*/
@@ -191,7 +192,7 @@ public static ProjectionOperation project(Fields fields) {
191192

192193
/**
193194
* Factory method to create a new {@link UnwindOperation} for the field with the given name.
194-
*
195+
*
195196
* @param fieldName must not be {@literal null} or empty.
196197
* @return
197198
*/
@@ -201,7 +202,7 @@ public static UnwindOperation unwind(String field) {
201202

202203
/**
203204
* Creates a new {@link GroupOperation} for the given fields.
204-
*
205+
*
205206
* @param fields must not be {@literal null}.
206207
* @return
207208
*/
@@ -211,7 +212,7 @@ public static GroupOperation group(String... fields) {
211212

212213
/**
213214
* Creates a new {@link GroupOperation} for the given {@link Fields}.
214-
*
215+
*
215216
* @param fields must not be {@literal null}.
216217
* @return
217218
*/
@@ -221,7 +222,7 @@ public static GroupOperation group(Fields fields) {
221222

222223
/**
223224
* Factory method to create a new {@link SortOperation} for the given {@link Sort}.
224-
*
225+
*
225226
* @param sort must not be {@literal null}.
226227
* @return
227228
*/
@@ -231,7 +232,7 @@ public static SortOperation sort(Sort sort) {
231232

232233
/**
233234
* Factory method to create a new {@link SortOperation} for the given sort {@link Direction} and {@code fields}.
234-
*
235+
*
235236
* @param direction must not be {@literal null}.
236237
* @param fields must not be {@literal null}.
237238
* @return
@@ -242,7 +243,7 @@ public static SortOperation sort(Direction direction, String... fields) {
242243

243244
/**
244245
* Creates a new {@link SkipOperation} skipping the given number of elements.
245-
*
246+
*
246247
* @param elementsToSkip must not be less than zero.
247248
* @return
248249
*/
@@ -252,7 +253,7 @@ public static SkipOperation skip(int elementsToSkip) {
252253

253254
/**
254255
* Creates a new {@link LimitOperation} limiting the result to the given number of elements.
255-
*
256+
*
256257
* @param maxElements must not be less than zero.
257258
* @return
258259
*/
@@ -262,28 +263,48 @@ public static LimitOperation limit(long maxElements) {
262263

263264
/**
264265
* Creates a new {@link MatchOperation} using the given {@link Criteria}.
265-
*
266+
*
266267
* @param criteria must not be {@literal null}.
267268
* @return
268269
*/
269270
public static MatchOperation match(Criteria criteria) {
270271
return new MatchOperation(criteria);
271272
}
272273

274+
/**
275+
* Creates a new {@link LookupOperation} for the given fields.
276+
*
277+
* @param fields must not be {@literal null}.
278+
* @return
279+
*/
280+
public static LookupOperation lookup(String from, String localField, String foreignField, String as) {
281+
return lookup(field(from), field(localField), field(foreignField), field(as));
282+
}
283+
284+
/**
285+
* Creates a new {@link LookupOperation} for the given {@link Fields}.
286+
*
287+
* @param fields must not be {@literal null}.
288+
* @return
289+
*/
290+
public static LookupOperation lookup(Field from, Field localField, Field foreignField, Field as) {
291+
return new LookupOperation(from, localField, foreignField, as);
292+
}
293+
273294
/**
274295
* Creates a new {@link Fields} instance for the given field names.
275-
*
276-
* @see Fields#fields(String...)
296+
*
277297
* @param fields must not be {@literal null}.
278298
* @return
299+
* @see Fields#fields(String...)
279300
*/
280301
public static Fields fields(String... fields) {
281302
return Fields.fields(fields);
282303
}
283304

284305
/**
285306
* Creates a new {@link Fields} instance from the given field name and target reference.
286-
*
307+
*
287308
* @param name must not be {@literal null} or empty.
288309
* @param target must not be {@literal null} or empty.
289310
* @return
@@ -295,7 +316,7 @@ public static Fields bind(String name, String target) {
295316
/**
296317
* Creates a new {@link GeoNearOperation} instance from the given {@link NearQuery} and the{@code distanceField}. The
297318
* {@code distanceField} defines output field that contains the calculated distance.
298-
*
319+
*
299320
* @param query must not be {@literal null}.
300321
* @param distanceField must not be {@literal null} or empty.
301322
* @return
@@ -307,7 +328,7 @@ public static GeoNearOperation geoNear(NearQuery query, String distanceField) {
307328

308329
/**
309330
* Returns a new {@link AggregationOptions.Builder}.
310-
*
331+
*
311332
* @return
312333
* @since 1.6
313334
*/
@@ -317,7 +338,7 @@ public static AggregationOptions.Builder newAggregationOptions() {
317338

318339
/**
319340
* Converts this {@link Aggregation} specification to a {@link DBObject}.
320-
*
341+
*
321342
* @param inputCollectionName the name of the input collection
322343
* @return the {@code DBObject} representing this aggregation
323344
*/
@@ -331,8 +352,11 @@ public DBObject toDbObject(String inputCollectionName, AggregationOperationConte
331352
operationDocuments.add(operation.toDBObject(context));
332353

333354
if (operation instanceof FieldsExposingAggregationOperation) {
355+
boolean additional = operation instanceof AdditionalFieldsExposingAggregationOperation ? true : false;
356+
334357
FieldsExposingAggregationOperation exposedFieldsOperation = (FieldsExposingAggregationOperation) operation;
335-
context = new ExposedFieldsAggregationOperationContext(exposedFieldsOperation.getFields(), rootContext);
358+
context = new ExposedFieldsAggregationOperationContext(exposedFieldsOperation.getFields(), rootContext,
359+
additional);
336360
}
337361
}
338362

@@ -356,7 +380,7 @@ public String toString() {
356380

357381
/**
358382
* Simple {@link AggregationOperationContext} that just returns {@link FieldReference}s as is.
359-
*
383+
*
360384
* @author Oliver Gierke
361385
*/
362386
private static class NoOpAggregationOperationContext implements AggregationOperationContext {
@@ -391,7 +415,7 @@ public FieldReference getReference(String name) {
391415

392416
/**
393417
* Describes the system variables available in MongoDB aggregation framework pipeline expressions.
394-
*
418+
*
395419
* @author Thomas Darimont
396420
* @see http://docs.mongodb.org/manual/reference/aggregation-variables
397421
*/
@@ -404,7 +428,7 @@ enum SystemVariable {
404428
/**
405429
* Return {@literal true} if the given {@code fieldRef} denotes a well-known system variable, {@literal false}
406430
* otherwise.
407-
*
431+
*
408432
* @param fieldRef may be {@literal null}.
409433
* @return
410434
*/

0 commit comments

Comments
 (0)