@@ -299,9 +299,14 @@ public static Bson lookup(final String from, final String localField, final Stri
299
299
}
300
300
301
301
/**
302
- * Creates a $lookup pipeline stage, joining the current collection with the one specified in from using the given pipeline
303
- *
304
- * @param from the name of the collection in the same database to perform the join with.
302
+ * Creates a $lookup pipeline stage, joining the current collection with the
303
+ * one specified in from using the given pipeline. If the first stage in the
304
+ * pipeline is a {@link Aggregates#documents(List) $documents} stage, then
305
+ * the {@code from} collection is ignored.
306
+ *
307
+ * @param from the name of the collection in the same database to
308
+ * perform the join with. May be {$code null} if the
309
+ * first pipeline stage is $documents.
305
310
* @param pipeline the pipeline to run on the joined collection.
306
311
* @param as the name of the new array field to add to the input documents.
307
312
* @return the $lookup pipeline stage
@@ -310,15 +315,20 @@ public static Bson lookup(final String from, final String localField, final Stri
310
315
* @since 3.7
311
316
*
312
317
*/
313
- public static Bson lookup (final String from , final List <? extends Bson > pipeline , final String as ) {
318
+ public static Bson lookup (@ Nullable final String from , final List <? extends Bson > pipeline , final String as ) {
314
319
return lookup (from , null , pipeline , as );
315
320
}
316
321
317
322
/**
318
- * Creates a $lookup pipeline stage, joining the current collection with the one specified in from using the given pipeline
323
+ * Creates a $lookup pipeline stage, joining the current collection with the
324
+ * one specified in from using the given pipeline. If the first stage in the
325
+ * pipeline is a {@link Aggregates#documents(List) $documents} stage, then
326
+ * the {@code from} collection is ignored.
319
327
*
320
328
* @param <TExpression> the Variable value expression type
321
- * @param from the name of the collection in the same database to perform the join with.
329
+ * @param from the name of the collection in the same database to
330
+ * perform the join with. May be {$code null} if the
331
+ * first pipeline stage is $documents.
322
332
* @param let the variables to use in the pipeline field stages.
323
333
* @param pipeline the pipeline to run on the joined collection.
324
334
* @param as the name of the new array field to add to the input documents.
@@ -327,7 +337,7 @@ public static Bson lookup(final String from, final List<? extends Bson> pipeline
327
337
* @mongodb.server.release 3.6
328
338
* @since 3.7
329
339
*/
330
- public static <TExpression > Bson lookup (final String from , @ Nullable final List <Variable <TExpression >> let ,
340
+ public static <TExpression > Bson lookup (@ Nullable final String from , @ Nullable final List <Variable <TExpression >> let ,
331
341
final List <? extends Bson > pipeline , final String as ) {
332
342
return new LookupStage <>(from , let , pipeline , as );
333
343
}
@@ -928,7 +938,7 @@ public static Bson searchMeta(final SearchCollector collector, final SearchOptio
928
938
*
929
939
* @param fields the fields to exclude. May use dot notation.
930
940
* @return the $unset pipeline stage
931
- * @mongodb.driver.manual reference/operator/aggregation/project / $unset
941
+ * @mongodb.driver.manual reference/operator/aggregation/unset / $unset
932
942
* @mongodb.server.release 4.2
933
943
* @since 4.8
934
944
*/
@@ -941,7 +951,7 @@ public static Bson unset(final String... fields) {
941
951
*
942
952
* @param fields the fields to exclude. May use dot notation.
943
953
* @return the $unset pipeline stage
944
- * @mongodb.driver.manual reference/operator/aggregation/project / $unset
954
+ * @mongodb.driver.manual reference/operator/aggregation/unset / $unset
945
955
* @mongodb.server.release 4.2
946
956
* @since 4.8
947
957
*/
@@ -962,7 +972,7 @@ public static Bson unset(final List<String> fields) {
962
972
* To specify a field within an embedded document, use dot notation.
963
973
* @param options {@link GeoNearOptions}
964
974
* @return the $geoNear pipeline stage
965
- * @mongodb.driver.manual reference/operator/aggregation/project / $geoNear
975
+ * @mongodb.driver.manual reference/operator/aggregation/geoNear / $geoNear
966
976
* @since 4.8
967
977
*/
968
978
public static Bson geoNear (
@@ -1012,7 +1022,7 @@ public String toString() {
1012
1022
* @param distanceField The output field that contains the calculated distance.
1013
1023
* To specify a field within an embedded document, use dot notation.
1014
1024
* @return the $geoNear pipeline stage
1015
- * @mongodb.driver.manual reference/operator/aggregation/project / $geoNear
1025
+ * @mongodb.driver.manual reference/operator/aggregation/geoNear / $geoNear
1016
1026
* @since 4.8
1017
1027
*/
1018
1028
public static Bson geoNear (
@@ -1021,6 +1031,33 @@ public static Bson geoNear(
1021
1031
return geoNear (near , distanceField , geoNearOptions ());
1022
1032
}
1023
1033
1034
+ /**
1035
+ * Creates a $documents pipeline stage.
1036
+ *
1037
+ * @param documents the documents.
1038
+ * @return the $documents pipeline stage.
1039
+ * @mongodb.driver.manual reference/operator/aggregation/documents/ $documents
1040
+ * @mongodb.server.release 5.1
1041
+ * @since 4.9
1042
+ */
1043
+ public static Bson documents (final List <? extends Bson > documents ) {
1044
+ notNull ("documents" , documents );
1045
+ return new Bson () {
1046
+ @ Override
1047
+ public <TDocument > BsonDocument toBsonDocument (final Class <TDocument > documentClass , final CodecRegistry codecRegistry ) {
1048
+ BsonDocumentWriter writer = new BsonDocumentWriter (new BsonDocument ());
1049
+ writer .writeStartDocument ();
1050
+ writer .writeStartArray ("$documents" );
1051
+ for (Bson bson : documents ) {
1052
+ BuildersHelper .encodeValue (writer , bson , codecRegistry );
1053
+ }
1054
+ writer .writeEndArray ();
1055
+ writer .writeEndDocument ();
1056
+ return writer .getDocument ();
1057
+ }
1058
+ };
1059
+ }
1060
+
1024
1061
static void writeBucketOutput (final CodecRegistry codecRegistry , final BsonDocumentWriter writer ,
1025
1062
@ Nullable final List <BsonField > output ) {
1026
1063
if (output != null ) {
@@ -1242,8 +1279,11 @@ private static final class LookupStage<TExpression> implements Bson {
1242
1279
private final List <? extends Bson > pipeline ;
1243
1280
private final String as ;
1244
1281
1245
- private LookupStage (final String from , @ Nullable final List <Variable <TExpression >> let , final List <? extends Bson > pipeline ,
1246
- final String as ) {
1282
+ private LookupStage (
1283
+ @ Nullable final String from ,
1284
+ @ Nullable final List <Variable <TExpression >> let ,
1285
+ final List <? extends Bson > pipeline ,
1286
+ final String as ) {
1247
1287
this .from = from ;
1248
1288
this .let = let ;
1249
1289
this .pipeline = pipeline ;
@@ -1258,7 +1298,9 @@ public <TDocument> BsonDocument toBsonDocument(final Class<TDocument> tDocumentC
1258
1298
1259
1299
writer .writeStartDocument ("$lookup" );
1260
1300
1261
- writer .writeString ("from" , from );
1301
+ if (from != null ) {
1302
+ writer .writeString ("from" , from );
1303
+ }
1262
1304
1263
1305
if (let != null ) {
1264
1306
writer .writeStartDocument ("let" );
0 commit comments