@@ -3281,8 +3281,7 @@ public FindIterable<Document> prepare(FindIterable<Document> cursor) {
3281
3281
3282
3282
Meta meta = query .getMeta ();
3283
3283
if (query .getSkip () <= 0 && query .getLimit () <= 0 && ObjectUtils .isEmpty (query .getSortObject ())
3284
- && !StringUtils .hasText (query .getHint ()) && !meta .hasValues ()
3285
- && !query .getCollation ().isPresent ()) {
3284
+ && !StringUtils .hasText (query .getHint ()) && !meta .hasValues () && !query .getCollation ().isPresent ()) {
3286
3285
return cursor ;
3287
3286
}
3288
3287
@@ -3302,15 +3301,30 @@ public FindIterable<Document> prepare(FindIterable<Document> cursor) {
3302
3301
cursorToUse = cursorToUse .sort (sort );
3303
3302
}
3304
3303
3305
- Document metaDocument = new Document ();
3306
3304
if (StringUtils .hasText (query .getHint ())) {
3307
- metaDocument . put ( "$ hint" , query .getHint ());
3305
+ cursorToUse = cursorToUse . hint ( Document . parse ( query .getHint () ));
3308
3306
}
3309
3307
3310
3308
if (meta .hasValues ()) {
3311
3309
3312
- for (Entry <String , Object > entry : meta .values ()) {
3313
- metaDocument .put (entry .getKey (), entry .getValue ());
3310
+ if (StringUtils .hasText (meta .getComment ())) {
3311
+ cursorToUse = cursorToUse .comment (meta .getComment ());
3312
+ }
3313
+
3314
+ if (meta .getSnapshot ()) {
3315
+ cursorToUse = cursorToUse .snapshot (meta .getSnapshot ());
3316
+ }
3317
+
3318
+ if (meta .getMaxScan () != null ) {
3319
+ cursorToUse = cursorToUse .maxScan (meta .getMaxScan ());
3320
+ }
3321
+
3322
+ if (meta .getMaxTimeMsec () != null ) {
3323
+ cursorToUse = cursorToUse .maxTime (meta .getMaxTimeMsec (), TimeUnit .MILLISECONDS );
3324
+ }
3325
+
3326
+ if (meta .getCursorBatchSize () != null ) {
3327
+ cursorToUse = cursorToUse .batchSize (meta .getCursorBatchSize ());
3314
3328
}
3315
3329
3316
3330
for (Meta .CursorOption option : meta .getFlags ()) {
@@ -3327,13 +3341,8 @@ public FindIterable<Document> prepare(FindIterable<Document> cursor) {
3327
3341
throw new IllegalArgumentException (String .format ("%s is no supported flag." , option ));
3328
3342
}
3329
3343
}
3330
-
3331
- if (meta .getCursorBatchSize () != null ) {
3332
- cursorToUse = cursorToUse .batchSize (meta .getCursorBatchSize ());
3333
- }
3334
3344
}
3335
3345
3336
- cursorToUse = cursorToUse .modifiers (metaDocument );
3337
3346
} catch (RuntimeException e ) {
3338
3347
throw potentiallyConvertRuntimeException (e , exceptionTranslator );
3339
3348
}
@@ -3464,149 +3473,6 @@ public MongoDbFactory getMongoDbFactory() {
3464
3473
return mongoDbFactory ;
3465
3474
}
3466
3475
3467
- /**
3468
- * {@link BatchAggregationLoader} is a little helper that can process cursor results returned by an aggregation
3469
- * command execution. On presence of a {@literal nextBatch} indicated by presence of an {@code id} field in the
3470
- * {@code cursor} another {@code getMore} command gets executed reading the next batch of documents until all results
3471
- * are loaded.
3472
- *
3473
- * @author Christoph Strobl
3474
- * @since 1.10
3475
- */
3476
- static class BatchAggregationLoader {
3477
-
3478
- private static final String CURSOR_FIELD = "cursor" ;
3479
- private static final String RESULT_FIELD = "result" ;
3480
- private static final String BATCH_SIZE_FIELD = "batchSize" ;
3481
- private static final String FIRST_BATCH = "firstBatch" ;
3482
- private static final String NEXT_BATCH = "nextBatch" ;
3483
- private static final String SERVER_USED = "serverUsed" ;
3484
- private static final String OK = "ok" ;
3485
-
3486
- private final MongoTemplate template ;
3487
- private final ReadPreference readPreference ;
3488
- private final int batchSize ;
3489
-
3490
- BatchAggregationLoader (MongoTemplate template , ReadPreference readPreference , int batchSize ) {
3491
-
3492
- this .template = template ;
3493
- this .readPreference = readPreference ;
3494
- this .batchSize = batchSize ;
3495
- }
3496
-
3497
- /**
3498
- * Run aggregation command and fetch all results.
3499
- */
3500
- Document aggregate (String collectionName , Aggregation aggregation , AggregationOperationContext context ) {
3501
-
3502
- Document command = prepareAggregationCommand (collectionName , aggregation , context , batchSize );
3503
-
3504
- if (LOGGER .isDebugEnabled ()) {
3505
- LOGGER .debug ("Executing aggregation: {}" , serializeToJsonSafely (command ));
3506
- }
3507
-
3508
- return mergeAggregationResults (aggregateBatched (command , collectionName , batchSize ));
3509
- }
3510
-
3511
- /**
3512
- * Pre process the aggregation command sent to the server by adding {@code cursor} options to match execution on
3513
- * different server versions.
3514
- */
3515
- private static Document prepareAggregationCommand (String collectionName , Aggregation aggregation ,
3516
- @ Nullable AggregationOperationContext context , int batchSize ) {
3517
-
3518
- AggregationOperationContext rootContext = context == null ? Aggregation .DEFAULT_CONTEXT : context ;
3519
- Document command = aggregation .toDocument (collectionName , rootContext );
3520
-
3521
- if (!aggregation .getOptions ().isExplain ()) {
3522
- command .put (CURSOR_FIELD , new Document (BATCH_SIZE_FIELD , batchSize ));
3523
- }
3524
-
3525
- return command ;
3526
- }
3527
-
3528
- private List <Document > aggregateBatched (Document command , String collectionName , int batchSize ) {
3529
-
3530
- List <Document > results = new ArrayList <>();
3531
-
3532
- Document commandResult = template .executeCommand (command , readPreference );
3533
- results .add (postProcessResult (commandResult ));
3534
-
3535
- while (hasNext (commandResult )) {
3536
-
3537
- Document getMore = new Document ("getMore" , getNextBatchId (commandResult )) //
3538
- .append ("collection" , collectionName ) //
3539
- .append (BATCH_SIZE_FIELD , batchSize );
3540
-
3541
- commandResult = template .executeCommand (getMore , this .readPreference );
3542
- results .add (postProcessResult (commandResult ));
3543
- }
3544
-
3545
- return results ;
3546
- }
3547
-
3548
- private static Document postProcessResult (Document commandResult ) {
3549
-
3550
- if (!commandResult .containsKey (CURSOR_FIELD )) {
3551
- return commandResult ;
3552
- }
3553
-
3554
- Document resultObject = new Document (SERVER_USED , commandResult .get (SERVER_USED ));
3555
- resultObject .put (OK , commandResult .get (OK ));
3556
-
3557
- Document cursor = (Document ) commandResult .get (CURSOR_FIELD );
3558
- if (cursor .containsKey (FIRST_BATCH )) {
3559
- resultObject .put (RESULT_FIELD , cursor .get (FIRST_BATCH ));
3560
- } else {
3561
- resultObject .put (RESULT_FIELD , cursor .get (NEXT_BATCH ));
3562
- }
3563
-
3564
- return resultObject ;
3565
- }
3566
-
3567
- private static Document mergeAggregationResults (List <Document > batchResults ) {
3568
-
3569
- if (batchResults .size () == 1 ) {
3570
- return batchResults .iterator ().next ();
3571
- }
3572
-
3573
- Document commandResult = new Document ();
3574
- List <Object > allResults = new ArrayList <>();
3575
-
3576
- for (Document batchResult : batchResults ) {
3577
-
3578
- Collection documents = (Collection <?>) batchResult .get (RESULT_FIELD );
3579
- if (!CollectionUtils .isEmpty (documents )) {
3580
- allResults .addAll (documents );
3581
- }
3582
- }
3583
-
3584
- // take general info from first batch
3585
- commandResult .put (SERVER_USED , batchResults .iterator ().next ().get (SERVER_USED ));
3586
- commandResult .put (OK , batchResults .iterator ().next ().get (OK ));
3587
-
3588
- // and append the merged batchResults
3589
- commandResult .put (RESULT_FIELD , allResults );
3590
-
3591
- return commandResult ;
3592
- }
3593
-
3594
- private static boolean hasNext (Document commandResult ) {
3595
-
3596
- if (!commandResult .containsKey (CURSOR_FIELD )) {
3597
- return false ;
3598
- }
3599
-
3600
- Object next = getNextBatchId (commandResult );
3601
- return next != null && ((Number ) next ).longValue () != 0L ;
3602
- }
3603
-
3604
- @ Nullable
3605
- private static Object getNextBatchId (Document commandResult ) {
3606
- return ((Document ) commandResult .get (CURSOR_FIELD )).get ("id" );
3607
- }
3608
- }
3609
-
3610
3476
/**
3611
3477
* {@link MongoTemplate} extension bound to a specific {@link ClientSession} that is applied when interacting with the
3612
3478
* server through the driver API.
0 commit comments