0
# Query and Aggregation
1
2
Advanced querying capabilities including complex filtering, sorting, projection, aggregation pipelines, MapReduce operations, and distinct value queries.
3
4
## Capabilities
5
6
### FindIterable Interface
7
8
Rich query interface providing filtering, sorting, projection, and cursor options for document retrieval.
9
10
```java { .api }
11
/**
12
* Interface for configuring and executing find queries
13
*/
14
public interface FindIterable<TResult> extends MongoIterable<TResult> {
15
/**
16
* Sets the query filter to limit results
17
* @param filter the query filter as Bson
18
* @return FindIterable with applied filter
19
*/
20
FindIterable<TResult> filter(Bson filter);
21
22
/**
23
* Sets the sort criteria for results
24
* @param sort the sort specification as Bson
25
* @return FindIterable with applied sort
26
*/
27
FindIterable<TResult> sort(Bson sort);
28
29
/**
30
* Sets the projection to limit returned fields
31
* @param projection the projection specification as Bson
32
* @return FindIterable with applied projection
33
*/
34
FindIterable<TResult> projection(Bson projection);
35
36
/**
37
* Sets the maximum number of documents to return
38
* @param limit the maximum number of documents
39
* @return FindIterable with applied limit
40
*/
41
FindIterable<TResult> limit(int limit);
42
43
/**
44
* Sets the number of documents to skip
45
* @param skip the number of documents to skip
46
* @return FindIterable with applied skip
47
*/
48
FindIterable<TResult> skip(int skip);
49
50
/**
51
* Sets the cursor type for the query
52
* @param cursorType the cursor type (TAILABLE, TAILABLE_AWAIT, etc.)
53
* @return FindIterable with specified cursor type
54
*/
55
FindIterable<TResult> cursorType(CursorType cursorType);
56
57
/**
58
* Sets whether to allow disk use for large result sets
59
* @param allowDiskUse true to allow disk use
60
* @return FindIterable with disk use option
61
*/
62
FindIterable<TResult> allowDiskUse(Boolean allowDiskUse);
63
64
/**
65
* Sets the maximum execution time
66
* @param maxTime the maximum time
67
* @param timeUnit the time unit
68
* @return FindIterable with time limit
69
*/
70
FindIterable<TResult> maxTime(long maxTime, TimeUnit timeUnit);
71
72
/**
73
* Sets collation for string comparisons
74
* @param collation the collation specification
75
* @return FindIterable with applied collation
76
*/
77
FindIterable<TResult> collation(Collation collation);
78
79
/**
80
* Explains the query execution plan
81
* @param verbosity the level of detail for explanation
82
* @return query execution plan as Document
83
*/
84
Document explain(ExplainVerbosity verbosity);
85
}
86
```
87
88
**Usage Examples:**
89
90
```java
91
import com.mongodb.client.model.Filters;
92
import com.mongodb.client.model.Sorts;
93
import com.mongodb.client.model.Projections;
94
95
// Complex query with multiple conditions
96
FindIterable<Document> results = collection.find()
97
.filter(Filters.and(
98
Filters.gte("age", 18),
99
Filters.lt("age", 65),
100
Filters.eq("status", "active"),
101
Filters.in("department", Arrays.asList("sales", "marketing"))
102
))
103
.sort(Sorts.orderBy(Sorts.ascending("lastName"), Sorts.descending("age")))
104
.projection(Projections.include("firstName", "lastName", "email", "department"))
105
.limit(20)
106
.skip(10);
107
108
// Execute query
109
for (Document doc : results) {
110
System.out.println(doc.toJson());
111
}
112
113
// Text search with sorting by relevance
114
FindIterable<Document> textResults = collection.find()
115
.filter(Filters.text("java mongodb driver"))
116
.sort(Sorts.metaTextScore("score"))
117
.projection(Projections.metaTextScore("score"));
118
119
// Explain query performance
120
Document explanation = collection.find()
121
.filter(Filters.eq("category", "electronics"))
122
.explain(ExplainVerbosity.EXECUTION_STATS);
123
System.out.println("Query plan: " + explanation.toJson());
124
```
125
126
### AggregateIterable Interface
127
128
Aggregation pipeline interface for complex data processing and transformation operations.
129
130
```java { .api }
131
/**
132
* Interface for configuring and executing aggregation pipelines
133
*/
134
public interface AggregateIterable<TResult> extends MongoIterable<TResult> {
135
/**
136
* Enables or disables the use of disk for large aggregations
137
* @param allowDiskUse true to allow disk usage
138
* @return AggregateIterable with disk use option
139
*/
140
AggregateIterable<TResult> allowDiskUse(Boolean allowDiskUse);
141
142
/**
143
* Sets the maximum execution time
144
* @param maxTime the maximum time
145
* @param timeUnit the time unit
146
* @return AggregateIterable with time limit
147
*/
148
AggregateIterable<TResult> maxTime(long maxTime, TimeUnit timeUnit);
149
150
/**
151
* Enables bypassing document validation for write stages
152
* @param bypassDocumentValidation true to bypass validation
153
* @return AggregateIterable with validation bypass
154
*/
155
AggregateIterable<TResult> bypassDocumentValidation(Boolean bypassDocumentValidation);
156
157
/**
158
* Sets collation for string operations in the pipeline
159
* @param collation the collation specification
160
* @return AggregateIterable with applied collation
161
*/
162
AggregateIterable<TResult> collation(Collation collation);
163
164
/**
165
* Provides a hint for which index to use
166
* @param hint the index hint as Bson
167
* @return AggregateIterable with index hint
168
*/
169
AggregateIterable<TResult> hint(Bson hint);
170
171
/**
172
* Writes aggregation results to a collection (for $out or $merge stages)
173
*/
174
void toCollection();
175
176
/**
177
* Explains the aggregation execution plan
178
* @param verbosity the level of detail for explanation
179
* @return aggregation execution plan as Document
180
*/
181
Document explain(ExplainVerbosity verbosity);
182
}
183
```
184
185
**Usage Examples:**
186
187
```java
188
import com.mongodb.client.model.Aggregates;
189
import com.mongodb.client.model.Accumulators;
190
import com.mongodb.client.model.Sorts;
191
192
// Sales analytics aggregation pipeline
193
List<Bson> pipeline = Arrays.asList(
194
// Filter recent orders
195
Aggregates.match(Filters.gte("orderDate", LocalDate.now().minusDays(30))),
196
197
// Lookup customer information
198
Aggregates.lookup("customers", "customerId", "_id", "customer"),
199
200
// Unwind customer array
201
Aggregates.unwind("$customer"),
202
203
// Group by customer and calculate totals
204
Aggregates.group("$customer.region",
205
Accumulators.sum("totalSales", "$amount"),
206
Accumulators.avg("avgOrderValue", "$amount"),
207
Accumulators.sum("orderCount", 1)
208
),
209
210
// Sort by total sales descending
211
Aggregates.sort(Sorts.descending("totalSales")),
212
213
// Add computed fields
214
Aggregates.addFields(new Field("salesPerOrder",
215
new Document("$divide", Arrays.asList("$totalSales", "$orderCount"))))
216
);
217
218
// Execute aggregation
219
AggregateIterable<Document> results = collection.aggregate(pipeline)
220
.allowDiskUse(true)
221
.maxTime(30, TimeUnit.SECONDS);
222
223
for (Document result : results) {
224
System.out.println("Region: " + result.getString("_id"));
225
System.out.println("Total Sales: " + result.getDouble("totalSales"));
226
System.out.println("Average Order: " + result.getDouble("avgOrderValue"));
227
}
228
229
// Complex aggregation with faceted search
230
List<Bson> facetPipeline = Arrays.asList(
231
Aggregates.match(Filters.eq("status", "published")),
232
Aggregates.facet(
233
new Facet("categories",
234
Aggregates.group("$category", Accumulators.sum("count", 1)),
235
Aggregates.sort(Sorts.descending("count"))
236
),
237
new Facet("priceRanges",
238
Aggregates.bucket("$price",
239
Arrays.asList(0, 50, 100, 500, 1000),
240
new BucketOptions().defaultBucket("1000+")
241
.output(Accumulators.sum("count", 1))
242
)
243
),
244
new Facet("dateHistogram",
245
Aggregates.group(
246
new Document("$dateToString",
247
new Document("format", "%Y-%m")
248
.append("date", "$createdDate")
249
),
250
Accumulators.sum("count", 1)
251
)
252
)
253
)
254
);
255
256
Document facetResults = collection.aggregate(facetPipeline).first();
257
System.out.println("Faceted results: " + facetResults.toJson());
258
```
259
260
### DistinctIterable Interface
261
262
Interface for retrieving distinct values from a collection field.
263
264
```java { .api }
265
/**
266
* Interface for distinct value queries
267
*/
268
public interface DistinctIterable<TResult> extends MongoIterable<TResult> {
269
/**
270
* Sets the query filter to limit which documents are examined
271
* @param filter the query filter as Bson
272
* @return DistinctIterable with applied filter
273
*/
274
DistinctIterable<TResult> filter(Bson filter);
275
276
/**
277
* Sets the maximum execution time
278
* @param maxTime the maximum time
279
* @param timeUnit the time unit
280
* @return DistinctIterable with time limit
281
*/
282
DistinctIterable<TResult> maxTime(long maxTime, TimeUnit timeUnit);
283
284
/**
285
* Sets collation for string comparisons
286
* @param collation the collation specification
287
* @return DistinctIterable with applied collation
288
*/
289
DistinctIterable<TResult> collation(Collation collation);
290
}
291
```
292
293
**Usage Examples:**
294
295
```java
296
// Get distinct categories
297
DistinctIterable<String> categories = collection.distinct("category", String.class);
298
for (String category : categories) {
299
System.out.println("Category: " + category);
300
}
301
302
// Get distinct values with filter
303
DistinctIterable<String> activeUserCountries = collection
304
.distinct("country", String.class)
305
.filter(Filters.eq("status", "active"));
306
307
List<String> countries = new ArrayList<>();
308
activeUserCountries.into(countries);
309
System.out.println("Active user countries: " + countries);
310
311
// Get distinct with complex filter
312
DistinctIterable<Integer> distinctAges = collection
313
.distinct("age", Integer.class)
314
.filter(Filters.and(
315
Filters.gte("registrationDate", LocalDate.now().minusYears(1)),
316
Filters.eq("verified", true)
317
));
318
```
319
320
### MapReduceIterable Interface
321
322
Interface for MapReduce operations (legacy approach, aggregation preferred).
323
324
```java { .api }
325
/**
326
* Interface for MapReduce operations
327
*/
328
public interface MapReduceIterable<TResult> extends MongoIterable<TResult> {
329
/**
330
* Sets the name of the collection to output results to
331
* @param collectionName the output collection name
332
* @return MapReduceIterable with output collection
333
*/
334
MapReduceIterable<TResult> collectionName(String collectionName);
335
336
/**
337
* Sets the finalize function for post-processing
338
* @param finalizeFunction JavaScript function as string
339
* @return MapReduceIterable with finalize function
340
*/
341
MapReduceIterable<TResult> finalizeFunction(String finalizeFunction);
342
343
/**
344
* Sets the scope variables available to map, reduce, and finalize functions
345
* @param scope the scope variables as Bson
346
* @return MapReduceIterable with scope variables
347
*/
348
MapReduceIterable<TResult> scope(Bson scope);
349
350
/**
351
* Sets the sort criteria to apply before mapping
352
* @param sort the sort specification as Bson
353
* @return MapReduceIterable with applied sort
354
*/
355
MapReduceIterable<TResult> sort(Bson sort);
356
357
/**
358
* Sets the query filter to limit input documents
359
* @param filter the query filter as Bson
360
* @return MapReduceIterable with applied filter
361
*/
362
MapReduceIterable<TResult> filter(Bson filter);
363
364
/**
365
* Sets the maximum number of documents to process
366
* @param limit the maximum number of documents
367
* @return MapReduceIterable with applied limit
368
*/
369
MapReduceIterable<TResult> limit(int limit);
370
371
/**
372
* Sets the MapReduce action (output behavior)
373
* @param action the MapReduce action
374
* @return MapReduceIterable with specified action
375
*/
376
MapReduceIterable<TResult> action(MapReduceAction action);
377
378
/**
379
* Writes results to a collection
380
*/
381
void toCollection();
382
}
383
```
384
385
**Usage Examples:**
386
387
```java
388
// MapReduce for counting documents by category (better done with aggregation)
389
String mapFunction = "function() { emit(this.category, 1); }";
390
String reduceFunction = "function(key, values) { return Array.sum(values); }";
391
392
MapReduceIterable<Document> mapReduceResults = collection
393
.mapReduce(mapFunction, reduceFunction)
394
.filter(Filters.eq("status", "active"));
395
396
for (Document result : mapReduceResults) {
397
System.out.println("Category: " + result.getString("_id") +
398
", Count: " + result.getInteger("value"));
399
}
400
401
// Note: Modern applications should use aggregation instead:
402
List<Bson> equivalentAggregation = Arrays.asList(
403
Aggregates.match(Filters.eq("status", "active")),
404
Aggregates.group("$category", Accumulators.sum("count", 1))
405
);
406
```
407
408
### Query Optimization
409
410
Advanced querying techniques for performance optimization.
411
412
```java { .api }
413
// Index hints for query optimization
414
FindIterable<Document> optimizedQuery = collection.find()
415
.filter(Filters.and(
416
Filters.gte("timestamp", startDate),
417
Filters.lt("timestamp", endDate),
418
Filters.eq("userId", userId)
419
))
420
.hint(new Document("userId", 1).append("timestamp", 1))
421
.sort(Sorts.descending("timestamp"));
422
423
// Partial results for large collections
424
FindIterable<Document> partialResults = collection.find()
425
.filter(complexFilter)
426
.partial(true) // Return partial results if some shards are down
427
.maxTime(5, TimeUnit.SECONDS);
428
429
// Cursor configuration for different use cases
430
FindIterable<Document> tailableCursor = collection.find()
431
.cursorType(CursorType.TailableAwait)
432
.maxAwaitTime(1, TimeUnit.SECONDS)
433
.noCursorTimeout(true);
434
```
435
436
### Query Result Processing
437
438
Different approaches for processing query results efficiently.
439
440
```java { .api }
441
// Iterator-based processing
442
try (MongoCursor<Document> cursor = collection.find().iterator()) {
443
while (cursor.hasNext()) {
444
Document doc = cursor.next();
445
// Process document
446
}
447
}
448
449
// Stream-like processing with forEach
450
collection.find()
451
.filter(Filters.eq("processed", false))
452
.forEach(document -> {
453
// Process each document
454
processDocument(document);
455
456
// Mark as processed
457
collection.updateOne(
458
Filters.eq("_id", document.getObjectId("_id")),
459
Updates.set("processed", true)
460
);
461
});
462
463
// Collect results into collections
464
List<Document> results = new ArrayList<>();
465
collection.find()
466
.filter(Filters.eq("category", "important"))
467
.into(results);
468
469
// Transform results
470
List<String> names = collection.find()
471
.projection(Projections.include("name"))
472
.map(doc -> doc.getString("name"))
473
.into(new ArrayList<>());
474
```