Skip to content

Commit aef6137

Browse files
committed
JAVA-2552: Support array filters in DBCollection
1 parent 36b60bd commit aef6137

14 files changed

+190
-51
lines changed

driver/src/main/com/mongodb/BulkUpdateRequestBuilder.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import com.mongodb.client.model.Collation;
2020
import org.bson.codecs.Encoder;
2121

22+
import java.util.List;
23+
2224
/**
2325
* A builder for a single update request.
2426
*
@@ -33,16 +35,18 @@ public class BulkUpdateRequestBuilder {
3335
private final Encoder<DBObject> queryCodec;
3436
private final Encoder<DBObject> replacementCodec;
3537
private Collation collation;
38+
private final List<? extends DBObject> arrayFilters;
3639

3740
BulkUpdateRequestBuilder(final BulkWriteOperation bulkWriteOperation, final DBObject query, final boolean upsert,
3841
final Encoder<DBObject> queryCodec, final Encoder<DBObject> replacementCodec,
39-
final Collation collation) {
42+
final Collation collation, final List<? extends DBObject> arrayFilters) {
4043
this.bulkWriteOperation = bulkWriteOperation;
4144
this.query = query;
4245
this.upsert = upsert;
4346
this.queryCodec = queryCodec;
4447
this.replacementCodec = replacementCodec;
4548
this.collation = collation;
49+
this.arrayFilters = arrayFilters;
4650
}
4751

4852
/**
@@ -69,6 +73,16 @@ public BulkUpdateRequestBuilder collation(final Collation collation) {
6973
return this;
7074
}
7175

76+
/**
77+
* Gets the array filters to apply to the update operation
78+
* @return the array filters, which may be null
79+
* @since 3.6
80+
* @mongodb.server.release 3.6
81+
*/
82+
public List<? extends DBObject> getArrayFilters() {
83+
return arrayFilters;
84+
}
85+
7286
/**
7387
* Adds a request to replace one document in the collection that matches the query with which this builder was created.
7488
*
@@ -85,7 +99,7 @@ public void replaceOne(final DBObject document) {
8599
* @param update the update criteria
86100
*/
87101
public void update(final DBObject update) {
88-
bulkWriteOperation.addRequest(new UpdateRequest(query, update, true, upsert, queryCodec, collation));
102+
bulkWriteOperation.addRequest(new UpdateRequest(query, update, true, upsert, queryCodec, collation, arrayFilters));
89103
}
90104

91105
/**
@@ -94,6 +108,6 @@ public void update(final DBObject update) {
94108
* @param update the update criteria
95109
*/
96110
public void updateOne(final DBObject update) {
97-
bulkWriteOperation.addRequest(new UpdateRequest(query, update, false, upsert, queryCodec, collation));
111+
bulkWriteOperation.addRequest(new UpdateRequest(query, update, false, upsert, queryCodec, collation, arrayFilters));
98112
}
99113
}

driver/src/main/com/mongodb/BulkWriteHelper.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,6 @@ static List<BulkWriteError> translateWriteErrors(final List<com.mongodb.bulk.Bul
6969
return retVal;
7070
}
7171

72-
static List<com.mongodb.bulk.WriteRequest> translateWriteRequestsToNew(final List<WriteRequest> writeRequests) {
73-
List<com.mongodb.bulk.WriteRequest> retVal = new ArrayList<com.mongodb.bulk.WriteRequest>(writeRequests.size());
74-
for (WriteRequest cur : writeRequests) {
75-
retVal.add(cur.toNew());
76-
}
77-
return retVal;
78-
}
79-
8072
private BulkWriteHelper() {
8173
}
8274
}

driver/src/main/com/mongodb/BulkWriteRequestBuilder.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import com.mongodb.client.model.Collation;
2020
import org.bson.codecs.Encoder;
2121

22+
import java.util.List;
23+
2224
/**
2325
* A builder for a single write request.
2426
*
@@ -88,7 +90,7 @@ public void removeOne() {
8890
* update operators.
8991
*/
9092
public void replaceOne(final DBObject document) {
91-
new BulkUpdateRequestBuilder(bulkWriteOperation, query, false, codec, replacementCodec, collation).replaceOne(document);
93+
new BulkUpdateRequestBuilder(bulkWriteOperation, query, false, codec, replacementCodec, collation, null).replaceOne(document);
9294
}
9395

9496
/**
@@ -97,7 +99,7 @@ public void replaceOne(final DBObject document) {
9799
* @param update the update criteria
98100
*/
99101
public void update(final DBObject update) {
100-
new BulkUpdateRequestBuilder(bulkWriteOperation, query, false, codec, replacementCodec, collation).update(update);
102+
new BulkUpdateRequestBuilder(bulkWriteOperation, query, false, codec, replacementCodec, collation, null).update(update);
101103
}
102104

103105
/**
@@ -106,7 +108,7 @@ public void update(final DBObject update) {
106108
* @param update the update criteria
107109
*/
108110
public void updateOne(final DBObject update) {
109-
new BulkUpdateRequestBuilder(bulkWriteOperation, query, false, codec, replacementCodec, collation).updateOne(update);
111+
new BulkUpdateRequestBuilder(bulkWriteOperation, query, false, codec, replacementCodec, collation, null).updateOne(update);
110112
}
111113

112114
/**
@@ -116,6 +118,19 @@ public void updateOne(final DBObject update) {
116118
* @mongodb.driver.manual tutorial/modify-documents/#upsert-option Upsert
117119
*/
118120
public BulkUpdateRequestBuilder upsert() {
119-
return new BulkUpdateRequestBuilder(bulkWriteOperation, query, true, codec, replacementCodec, collation);
121+
return new BulkUpdateRequestBuilder(bulkWriteOperation, query, true, codec, replacementCodec, collation, null);
122+
}
123+
124+
/**
125+
* Specifies that the request being built should use the given array filters for an update. Note that this option only applies to
126+
* update operations and will be ignored for replace operations
127+
*
128+
* @param arrayFilters the array filters to apply to the update operation
129+
* @return a new builder that allows only update and replace, since upsert does not apply to remove.
130+
* @since 3.6
131+
* @mongodb.server.release 3.6
132+
*/
133+
public BulkUpdateRequestBuilder arrayFilters(final List<? extends DBObject> arrayFilters) {
134+
return new BulkUpdateRequestBuilder(bulkWriteOperation, query, false, codec, replacementCodec, collation, arrayFilters);
120135
}
121136
}

driver/src/main/com/mongodb/DBCollection.java

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474
import java.util.concurrent.TimeUnit;
7575

7676
import static com.mongodb.BulkWriteHelper.translateBulkWriteResult;
77-
import static com.mongodb.BulkWriteHelper.translateWriteRequestsToNew;
7877
import static com.mongodb.MongoNamespace.checkCollectionNameValidity;
7978
import static com.mongodb.ReadPreference.primary;
8079
import static com.mongodb.ReadPreference.primaryPreferred;
@@ -552,19 +551,15 @@ public WriteResult update(final DBObject query, final DBObject update, final DBC
552551
notNull("options", options);
553552
WriteConcern writeConcern = options.getWriteConcern() != null ? options.getWriteConcern() : getWriteConcern();
554553

555-
if (!update.keySet().isEmpty() && update.keySet().iterator().next().startsWith("$")) {
556-
UpdateRequest updateRequest = new UpdateRequest(wrap(query), wrap(update, options.getEncoder()),
557-
com.mongodb.bulk.WriteRequest.Type.UPDATE).upsert(options.isUpsert()).multi(options.isMulti())
558-
.collation(options.getCollation());
559-
return executeWriteOperation(new UpdateOperation(getNamespace(), false, writeConcern, singletonList(updateRequest))
560-
.bypassDocumentValidation(options.getBypassDocumentValidation()));
561-
} else {
562-
UpdateRequest replaceRequest = new UpdateRequest(wrap(query), wrap(update, options.getEncoder()),
563-
com.mongodb.bulk.WriteRequest.Type.REPLACE).upsert(options.isUpsert()).multi(options.isMulti())
564-
.collation(options.getCollation());
565-
return executeWriteOperation(new UpdateOperation(getNamespace(), true, writeConcern, singletonList(replaceRequest))
566-
.bypassDocumentValidation(options.getBypassDocumentValidation()));
567-
}
554+
com.mongodb.bulk.WriteRequest.Type updateType = !update.keySet().isEmpty() && update.keySet().iterator().next().startsWith("$")
555+
? com.mongodb.bulk.WriteRequest.Type.UPDATE
556+
: com.mongodb.bulk.WriteRequest.Type.REPLACE;
557+
UpdateRequest updateRequest = new UpdateRequest(wrap(query), wrap(update, options.getEncoder()), updateType)
558+
.upsert(options.isUpsert()).multi(options.isMulti())
559+
.collation(options.getCollation())
560+
.arrayFilters(wrapAllowNull(options.getArrayFilters(), options.getEncoder()));
561+
return executeWriteOperation(new UpdateOperation(getNamespace(), true, writeConcern, singletonList(updateRequest))
562+
.bypassDocumentValidation(options.getBypassDocumentValidation()));
568563
}
569564

570565
/**
@@ -1916,7 +1911,8 @@ public DBObject findAndModify(final DBObject query, final DBCollectionFindAndMod
19161911
.upsert(options.isUpsert())
19171912
.maxTime(options.getMaxTime(MILLISECONDS), MILLISECONDS)
19181913
.bypassDocumentValidation(options.getBypassDocumentValidation())
1919-
.collation(options.getCollation());
1914+
.collation(options.getCollation())
1915+
.arrayFilters(wrapAllowNull(options.getArrayFilters(), (Encoder<DBObject>) null));
19201916
} else {
19211917
operation = new FindAndReplaceOperation<DBObject>(getNamespace(), writeConcern, objectCodec,
19221918
wrap(options.getUpdate()))
@@ -2325,6 +2321,14 @@ BulkWriteResult executeBulkWriteOperation(final boolean ordered, final Boolean b
23252321
}
23262322
}
23272323

2324+
private List<com.mongodb.bulk.WriteRequest> translateWriteRequestsToNew(final List<WriteRequest> writeRequests) {
2325+
List<com.mongodb.bulk.WriteRequest> retVal = new ArrayList<com.mongodb.bulk.WriteRequest>(writeRequests.size());
2326+
for (WriteRequest cur : writeRequests) {
2327+
retVal.add(cur.toNew(this));
2328+
}
2329+
return retVal;
2330+
}
2331+
23282332
DBObjectCodec getDefaultDBObjectCodec() {
23292333
return new DBObjectCodec(MongoClient.getDefaultCodecRegistry(),
23302334
DBObjectCodec.getDefaultBsonTypeClassMap(),
@@ -2475,6 +2479,22 @@ BsonDocument wrapAllowNull(final DBObject document) {
24752479
return wrap(document);
24762480
}
24772481

2482+
List<BsonDocument> wrapAllowNull(final List<? extends DBObject> documentList, final DBEncoder encoder) {
2483+
return wrapAllowNull(documentList, encoder == null ? null : new DBEncoderAdapter(encoder));
2484+
}
2485+
2486+
List<BsonDocument> wrapAllowNull(final List<? extends DBObject> documentList, final Encoder<DBObject> encoder) {
2487+
if (documentList == null) {
2488+
return null;
2489+
}
2490+
List<BsonDocument> wrappedDocumentList = new ArrayList<BsonDocument>(documentList.size());
2491+
for (DBObject cur : documentList) {
2492+
wrappedDocumentList.add(encoder == null ? wrap(cur) : wrap(cur, encoder));
2493+
}
2494+
return wrappedDocumentList;
2495+
}
2496+
2497+
24782498
BsonDocument wrap(final DBObject document) {
24792499
return new BsonDocumentWrapper<DBObject>(document, getDefaultDBObjectCodec());
24802500
}

driver/src/main/com/mongodb/InsertRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public DBObject getDocument() {
3333
}
3434

3535
@Override
36-
com.mongodb.bulk.WriteRequest toNew() {
36+
com.mongodb.bulk.WriteRequest toNew(final DBCollection dbCollection) {
3737
return new com.mongodb.bulk.InsertRequest(new BsonDocumentWrapper<DBObject>(document, codec));
3838
}
3939
}

driver/src/main/com/mongodb/RemoveRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public boolean isMulti() {
4343
}
4444

4545
@Override
46-
com.mongodb.bulk.WriteRequest toNew() {
46+
com.mongodb.bulk.WriteRequest toNew(final DBCollection dbCollection) {
4747
return new DeleteRequest(new BsonDocumentWrapper<DBObject>(query, this.codec)).multi(isMulti()).collation(collation);
4848
}
4949
}

driver/src/main/com/mongodb/ReplaceRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public Collation getCollation() {
5555
}
5656

5757
@Override
58-
com.mongodb.bulk.WriteRequest toNew() {
58+
com.mongodb.bulk.WriteRequest toNew(final DBCollection dbCollection) {
5959
return new com.mongodb.bulk.UpdateRequest(new BsonDocumentWrapper<DBObject>(query, codec),
6060
new BsonDocumentWrapper<DBObject>(document, replacementCodec),
6161
com.mongodb.bulk.WriteRequest.Type.REPLACE)

driver/src/main/com/mongodb/UpdateRequest.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,26 @@
2020
import org.bson.BsonDocumentWrapper;
2121
import org.bson.codecs.Encoder;
2222

23+
import java.util.List;
24+
2325
class UpdateRequest extends WriteRequest {
2426
private final DBObject query;
2527
private final DBObject update;
2628
private final boolean multi;
2729
private final boolean upsert;
2830
private final Encoder<DBObject> codec;
2931
private final Collation collation;
32+
private final List<? extends DBObject> arrayFilters;
3033

3134
UpdateRequest(final DBObject query, final DBObject update, final boolean multi, final boolean upsert,
32-
final Encoder<DBObject> codec, final Collation collation) {
35+
final Encoder<DBObject> codec, final Collation collation, final List<? extends DBObject> arrayFilters) {
3336
this.query = query;
3437
this.update = update;
3538
this.multi = multi;
3639
this.upsert = upsert;
3740
this.codec = codec;
3841
this.collation = collation;
42+
this.arrayFilters = arrayFilters;
3943
}
4044

4145
public DBObject getQuery() {
@@ -58,13 +62,18 @@ public Collation getCollation() {
5862
return collation;
5963
}
6064

65+
public List<? extends DBObject> getArrayFilters() {
66+
return arrayFilters;
67+
}
68+
6169
@Override
62-
com.mongodb.bulk.WriteRequest toNew() {
70+
com.mongodb.bulk.WriteRequest toNew(final DBCollection dbCollection) {
6371
return new com.mongodb.bulk.UpdateRequest(new BsonDocumentWrapper<DBObject>(query, codec),
6472
new BsonDocumentWrapper<DBObject>(update, codec),
6573
com.mongodb.bulk.WriteRequest.Type.UPDATE)
6674
.upsert(isUpsert())
6775
.multi(isMulti())
68-
.collation(getCollation());
76+
.collation(getCollation())
77+
.arrayFilters(dbCollection.wrapAllowNull(arrayFilters, codec));
6978
}
7079
}

driver/src/main/com/mongodb/WriteRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
package com.mongodb;
1818

1919
abstract class WriteRequest {
20-
abstract com.mongodb.bulk.WriteRequest toNew();
20+
abstract com.mongodb.bulk.WriteRequest toNew(DBCollection dbCollection);
2121
}

driver/src/main/com/mongodb/client/model/DBCollectionFindAndModifyOptions.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.mongodb.DBObject;
2020
import com.mongodb.WriteConcern;
2121

22+
import java.util.List;
2223
import java.util.concurrent.TimeUnit;
2324

2425
import static com.mongodb.assertions.Assertions.isTrueArgument;
@@ -40,6 +41,7 @@ public final class DBCollectionFindAndModifyOptions {
4041
private long maxTimeMS;
4142
private WriteConcern writeConcern;
4243
private Collation collation;
44+
private List<? extends DBObject> arrayFilters;
4345

4446
/**
4547
* Construct a new instance
@@ -257,4 +259,28 @@ public DBCollectionFindAndModifyOptions collation(final Collation collation) {
257259
this.collation = collation;
258260
return this;
259261
}
262+
263+
/**
264+
* Sets the array filters option
265+
*
266+
* @param arrayFilters the array filters, which may be null
267+
* @return this
268+
* @since 3.6
269+
* @mongodb.server.release 3.6
270+
*/
271+
public DBCollectionFindAndModifyOptions arrayFilters(final List<? extends DBObject> arrayFilters) {
272+
this.arrayFilters = arrayFilters;
273+
return this;
274+
}
275+
276+
/**
277+
* Returns the array filters option
278+
*
279+
* @return the array filters, which may be null
280+
* @since 3.6
281+
* @mongodb.server.release 3.6
282+
*/
283+
public List<? extends DBObject> getArrayFilters() {
284+
return arrayFilters;
285+
}
260286
}

0 commit comments

Comments
 (0)