16
16
17
17
package com .mongodb .client .model ;
18
18
19
+ import com .mongodb .MongoNamespace ;
19
20
import com .mongodb .lang .Nullable ;
20
21
import org .bson .BsonBoolean ;
21
22
import org .bson .BsonDocument ;
22
23
import org .bson .BsonDocumentWriter ;
23
24
import org .bson .BsonInt32 ;
24
25
import org .bson .BsonString ;
26
+ import org .bson .BsonValue ;
25
27
import org .bson .codecs .configuration .CodecRegistry ;
26
28
import org .bson .conversions .Bson ;
27
29
@@ -411,7 +413,7 @@ public static Bson unwind(final String fieldName, final UnwindOptions unwindOpti
411
413
}
412
414
413
415
/**
414
- * Creates a $out pipeline stage for the specified filter
416
+ * Creates a $out pipeline stage that writes into the specified collection
415
417
*
416
418
* @param collectionName the collection name
417
419
* @return the $out pipeline stage
@@ -422,6 +424,61 @@ public static Bson out(final String collectionName) {
422
424
return new BsonDocument ("$out" , new BsonString (collectionName ));
423
425
}
424
426
427
+ /**
428
+ * Creates a $merge pipeline stage that merges into the specified collection
429
+ *
430
+ * @param collectionName the name of the collection to merge into
431
+ * @return the $merge pipeline stage
432
+ * @since 3.11
433
+ * @mongodb.driver.manual reference/operator/aggregation/merge/ $merge
434
+ * @mongodb.server.release 4.2
435
+ */
436
+ public static Bson merge (final String collectionName ) {
437
+ return merge (collectionName , new MergeOptions ());
438
+ }
439
+
440
+ /**
441
+ * Creates a $merge pipeline stage that merges into the specified namespace
442
+ *
443
+ * @param namespace the namespace to merge into
444
+ * @return the $merge pipeline stage
445
+ * @since 3.11
446
+ * @mongodb.driver.manual reference/operator/aggregation/merge/ $merge
447
+ * @mongodb.server.release 4.2
448
+ */
449
+ public static Bson merge (final MongoNamespace namespace ) {
450
+ return merge (namespace , new MergeOptions ());
451
+ }
452
+
453
+ /**
454
+ * Creates a $merge pipeline stage that merges into the specified collection using the specified options.
455
+ *
456
+ * @param collectionName the name of the collection to merge into
457
+ * @param options the merge options
458
+ * @return the $merge pipeline stage
459
+ * @since 3.11
460
+ * @mongodb.driver.manual reference/operator/aggregation/merge/ $merge
461
+ * @mongodb.server.release 4.2
462
+ */
463
+ public static Bson merge (final String collectionName , final MergeOptions options ) {
464
+ return new MergeStage (new BsonString (collectionName ), options );
465
+ }
466
+
467
+ /**
468
+ * Creates a $merge pipeline stage that merges into the specified namespace using the specified options.
469
+ *
470
+ * @param namespace the namespace to merge into
471
+ * @param options the merge options
472
+ * @return the $merge pipeline stage
473
+ * @since 3.11
474
+ * @mongodb.driver.manual reference/operator/aggregation/merge/ $merge
475
+ * @mongodb.server.release 4.2
476
+ */
477
+ public static Bson merge (final MongoNamespace namespace , final MergeOptions options ) {
478
+ return new MergeStage (new BsonDocument ("db" , new BsonString (namespace .getDatabaseName ()))
479
+ .append ("coll" , new BsonString (namespace .getCollectionName ())), options );
480
+ }
481
+
425
482
/**
426
483
* Creates a $replaceRoot pipeline stage
427
484
*
@@ -1132,6 +1189,136 @@ public String toString() {
1132
1189
}
1133
1190
}
1134
1191
1192
+ private static class MergeStage implements Bson {
1193
+ private final BsonValue intoValue ;
1194
+ private final MergeOptions options ;
1195
+
1196
+ MergeStage (final BsonValue intoValue , final MergeOptions options ) {
1197
+ this .intoValue = intoValue ;
1198
+ this .options = options ;
1199
+ }
1200
+
1201
+ @ Override
1202
+ public <TDocument > BsonDocument toBsonDocument (final Class <TDocument > documentClass , final CodecRegistry codecRegistry ) {
1203
+ BsonDocumentWriter writer = new BsonDocumentWriter (new BsonDocument ());
1204
+ writer .writeStartDocument ();
1205
+ writer .writeStartDocument ("$merge" );
1206
+ writer .writeName ("into" );
1207
+ if (intoValue .isString ()) {
1208
+ writer .writeString (intoValue .asString ().getValue ());
1209
+ } else {
1210
+ writer .writeStartDocument ();
1211
+ writer .writeString ("db" , intoValue .asDocument ().getString ("db" ).getValue ());
1212
+ writer .writeString ("coll" , intoValue .asDocument ().getString ("coll" ).getValue ());
1213
+ writer .writeEndDocument ();
1214
+ }
1215
+ if (options .getUniqueIdentifier () != null ) {
1216
+ if (options .getUniqueIdentifier ().size () == 1 ) {
1217
+ writer .writeString ("on" , options .getUniqueIdentifier ().get (0 ));
1218
+ } else {
1219
+ writer .writeStartArray ("on" );
1220
+ for (String cur : options .getUniqueIdentifier ()) {
1221
+ writer .writeString (cur );
1222
+ }
1223
+ writer .writeEndArray ();
1224
+ }
1225
+ }
1226
+ if (options .getVariables () != null ) {
1227
+ writer .writeStartDocument ("let" );
1228
+
1229
+ for (Variable <?> variable : options .getVariables ()) {
1230
+ writer .writeName (variable .getName ());
1231
+ BuildersHelper .encodeValue (writer , variable .getValue (), codecRegistry );
1232
+ }
1233
+
1234
+ writer .writeEndDocument ();
1235
+ }
1236
+
1237
+ if (options .getWhenMatched () != null ) {
1238
+ writer .writeName ("whenMatched" );
1239
+ switch (options .getWhenMatched ()) {
1240
+ case REPLACE :
1241
+ writer .writeString ("replace" );
1242
+ break ;
1243
+ case KEEP_EXISTING :
1244
+ writer .writeString ("keepExisting" );
1245
+ break ;
1246
+ case MERGE :
1247
+ writer .writeString ("merge" );
1248
+ break ;
1249
+ case PIPELINE :
1250
+ writer .writeStartArray ();
1251
+ for (Bson curStage : options .getWhenMatchedPipeline ()) {
1252
+ BuildersHelper .encodeValue (writer , curStage , codecRegistry );
1253
+ }
1254
+ writer .writeEndArray ();
1255
+ break ;
1256
+ case FAIL :
1257
+ writer .writeString ("fail" );
1258
+ break ;
1259
+ default :
1260
+ throw new UnsupportedOperationException ("Unexpected value: " + options .getWhenMatched ());
1261
+ }
1262
+ }
1263
+ if (options .getWhenNotMatched () != null ) {
1264
+ writer .writeName ("whenNotMatched" );
1265
+ switch (options .getWhenNotMatched ()) {
1266
+ case INSERT :
1267
+ writer .writeString ("insert" );
1268
+ break ;
1269
+ case DISCARD :
1270
+ writer .writeString ("discard" );
1271
+ break ;
1272
+ case FAIL :
1273
+ writer .writeString ("fail" );
1274
+ break ;
1275
+ default :
1276
+ throw new UnsupportedOperationException ("Unexpected value: " + options .getWhenNotMatched ());
1277
+ }
1278
+ }
1279
+ writer .writeEndDocument ();
1280
+ writer .writeEndDocument ();
1281
+ return writer .getDocument ();
1282
+ }
1283
+
1284
+ @ Override
1285
+ public boolean equals (final Object o ) {
1286
+ if (this == o ) {
1287
+ return true ;
1288
+ }
1289
+ if (o == null || getClass () != o .getClass ()) {
1290
+ return false ;
1291
+ }
1292
+
1293
+ MergeStage that = (MergeStage ) o ;
1294
+
1295
+ if (!intoValue .equals (that .intoValue )) {
1296
+ return false ;
1297
+ }
1298
+ if (!options .equals (that .options )) {
1299
+ return false ;
1300
+ }
1301
+
1302
+ return true ;
1303
+ }
1304
+
1305
+ @ Override
1306
+ public int hashCode () {
1307
+ int result = intoValue .hashCode ();
1308
+ result = 31 * result + options .hashCode ();
1309
+ return result ;
1310
+ }
1311
+
1312
+ @ Override
1313
+ public String toString () {
1314
+ return "Stage{"
1315
+ + "name='$merge', "
1316
+ + ", into=" + intoValue
1317
+ + ", options=" + options
1318
+ + '}' ;
1319
+ }
1320
+ }
1321
+
1135
1322
private Aggregates () {
1136
1323
}
1137
1324
}
0 commit comments