com.mongodb.DBCollection Maven / Gradle / Ivy
/*
* Copyright 2008-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mongodb;
import com.mongodb.annotations.ThreadSafe;
import com.mongodb.bulk.DeleteRequest;
import com.mongodb.bulk.IndexRequest;
import com.mongodb.bulk.InsertRequest;
import com.mongodb.bulk.UpdateRequest;
import com.mongodb.client.internal.MongoBatchCursorAdapter;
import com.mongodb.client.internal.MongoIterableImpl;
import com.mongodb.client.internal.OperationExecutor;
import com.mongodb.client.model.DBCollectionCountOptions;
import com.mongodb.client.model.DBCollectionDistinctOptions;
import com.mongodb.client.model.DBCollectionFindAndModifyOptions;
import com.mongodb.client.model.DBCollectionFindOptions;
import com.mongodb.client.model.DBCollectionRemoveOptions;
import com.mongodb.client.model.DBCollectionUpdateOptions;
import com.mongodb.connection.BufferProvider;
import com.mongodb.lang.Nullable;
import com.mongodb.operation.AggregateOperation;
import com.mongodb.operation.AggregateToCollectionOperation;
import com.mongodb.operation.BaseWriteOperation;
import com.mongodb.operation.BatchCursor;
import com.mongodb.operation.CountOperation;
import com.mongodb.operation.CreateIndexesOperation;
import com.mongodb.operation.DeleteOperation;
import com.mongodb.operation.DistinctOperation;
import com.mongodb.operation.DropCollectionOperation;
import com.mongodb.operation.DropIndexOperation;
import com.mongodb.operation.FindAndDeleteOperation;
import com.mongodb.operation.FindAndReplaceOperation;
import com.mongodb.operation.FindAndUpdateOperation;
import com.mongodb.operation.InsertOperation;
import com.mongodb.operation.ListIndexesOperation;
import com.mongodb.operation.MapReduceBatchCursor;
import com.mongodb.operation.MapReduceStatistics;
import com.mongodb.operation.MapReduceToCollectionOperation;
import com.mongodb.operation.MapReduceWithInlineResultsOperation;
import com.mongodb.operation.MixedBulkWriteOperation;
import com.mongodb.operation.ParallelCollectionScanOperation;
import com.mongodb.operation.ReadOperation;
import com.mongodb.operation.RenameCollectionOperation;
import com.mongodb.operation.UpdateOperation;
import com.mongodb.operation.WriteOperation;
import org.bson.BsonDocument;
import org.bson.BsonDocumentReader;
import org.bson.BsonDocumentWrapper;
import org.bson.BsonInt32;
import org.bson.BsonJavaScript;
import org.bson.BsonString;
import org.bson.BsonValue;
import org.bson.codecs.BsonDocumentCodec;
import org.bson.codecs.BsonValueCodec;
import org.bson.codecs.Codec;
import org.bson.codecs.Decoder;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.Encoder;
import org.bson.types.ObjectId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.mongodb.BulkWriteHelper.translateBulkWriteResult;
import static com.mongodb.MongoNamespace.checkCollectionNameValidity;
import static com.mongodb.ReadPreference.primary;
import static com.mongodb.ReadPreference.primaryPreferred;
import static com.mongodb.assertions.Assertions.notNull;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
/**
* Implementation of a database collection. A typical invocation sequence is thus:
*
* {@code
* MongoClient mongoClient = new MongoClient(new ServerAddress("localhost", 27017));
* DB db = mongoClient.getDB("mydb");
* DBCollection collection = db.getCollection("test"); }
*
* To get a collection to use, just specify the name of the collection to the getCollection(String collectionName) method:
*
* {@code
* DBCollection coll = db.getCollection("testCollection"); }
*
* Once you have the collection object, you can insert documents into the collection:
*
* {@code
* BasicDBObject doc = new BasicDBObject("name", "MongoDB").append("type", "database")
* .append("count", 1)
* .append("info", new BasicDBObject("x", 203).append("y", 102));
* coll.insert(doc); }
*
* To show that the document we inserted in the previous step is there, we can do a simple findOne() operation to get the first document in
* the collection:
*
* {@code
* DBObject myDoc = coll.findOne();
* System.out.println(myDoc); }
*
*
* See {@link Mongo#getDB(String)} for further information about the effective deprecation of this class.
*
* @mongodb.driver.manual reference/glossary/#term-collection Collection
*/
@ThreadSafe
@SuppressWarnings({"unchecked", "deprecation", "rawtypes","resource"})
public class DBCollection {
public static final String ID_FIELD_NAME = "_id";
private final String name;
private final DB database;
private final OperationExecutor executor;
private final Bytes.OptionHolder optionHolder;
private final boolean retryWrites;
private final boolean retryReads;
private volatile ReadPreference readPreference;
private volatile WriteConcern writeConcern;
private volatile ReadConcern readConcern;
private List hintFields;
private DBEncoderFactory encoderFactory;
private DBDecoderFactory decoderFactory;
private DBCollectionObjectFactory objectFactory;
private volatile CompoundDBObjectCodec objectCodec;
/**
* Constructs new {@code DBCollection} instance. This operation not reflected on the server.
* @param name the name of the collection
* @param database the database to which this collections belongs to
*/
DBCollection(final String name, final DB database, final OperationExecutor executor) {
checkCollectionNameValidity(name);
this.name = name;
this.database = database;
this.executor = executor;
this.optionHolder = new Bytes.OptionHolder(database.getOptionHolder());
this.objectFactory = new DBCollectionObjectFactory();
this.objectCodec = new CompoundDBObjectCodec(getDefaultDBObjectCodec());
this.retryWrites = database.getMongo().getMongoClientOptions().getRetryWrites();
this.retryReads = database.getMongo().getMongoClientOptions().getRetryReads();
}
/**
* Initializes a new collection. No operation is actually performed on the database.
*
* @param database database in which to create the collection
* @param name the name of the collection
*/
protected DBCollection(final DB database, final String name) {
this(name, database, database.getExecutor());
}
private static BasicDBList toDBList(final BatchCursor source) {
BasicDBList dbList = new BasicDBList();
while (source.hasNext()) {
dbList.addAll(source.next());
}
return dbList;
}
/**
* Insert a document into a collection. If the collection does not exists on the server, then it will be created. If the new document
* does not contain an '_id' field, it will be added.
*
* @param document {@code DBObject} to be inserted
* @param writeConcern {@code WriteConcern} to be used during operation
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/insert-documents/ Insert Documents
*/
public WriteResult insert(final DBObject document, final WriteConcern writeConcern) {
return insert(asList(document), writeConcern);
}
/**
* Insert documents into a collection. If the collection does not exists on the server, then it will be created. If the new document
* does not contain an '_id' field, it will be added. Collection wide {@code WriteConcern} will be used.
*
* @param documents {@code DBObject}'s to be inserted
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/insert-documents/ Insert Documents
*/
public WriteResult insert(final DBObject... documents) {
return insert(asList(documents), getWriteConcern());
}
/**
* Insert documents into a collection. If the collection does not exists on the server, then it will be created. If the new document
* does not contain an '_id' field, it will be added.
*
* @param documents {@code DBObject}'s to be inserted
* @param writeConcern {@code WriteConcern} to be used during operation
* @return the result of the operation
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws com.mongodb.MongoException if the write failed due some other failure
* @mongodb.driver.manual tutorial/insert-documents/ Insert Documents
*/
public WriteResult insert(final WriteConcern writeConcern, final DBObject... documents) {
return insert(documents, writeConcern);
}
/**
* Insert documents into a collection. If the collection does not exists on the server, then it will be created. If the new document
* does not contain an '_id' field, it will be added.
*
* @param documents {@code DBObject}'s to be inserted
* @param writeConcern {@code WriteConcern} to be used during operation
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/insert-documents/ Insert Documents
*/
public WriteResult insert(final DBObject[] documents, final WriteConcern writeConcern) {
return insert(asList(documents), writeConcern);
}
/**
* Insert documents into a collection. If the collection does not exists on the server, then it will be created. If the new document
* does not contain an '_id' field, it will be added.
*
* @param documents list of {@code DBObject} to be inserted
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/insert-documents/ Insert Documents
*/
public WriteResult insert(final List documents) {
return insert(documents, getWriteConcern());
}
/**
* Insert documents into a collection. If the collection does not exists on the server, then it will be created. If the new document
* does not contain an '_id' field, it will be added.
*
* @param documents list of {@code DBObject}'s to be inserted
* @param aWriteConcern {@code WriteConcern} to be used during operation
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/insert-documents/ Insert Documents
*/
public WriteResult insert(final List documents, final WriteConcern aWriteConcern) {
return insert(documents, aWriteConcern, null);
}
/**
* Insert documents into a collection. If the collection does not exists on the server, then it will be created. If the new document
* does not contain an '_id' field, it will be added.
*
* @param documents {@code DBObject}'s to be inserted
* @param aWriteConcern {@code WriteConcern} to be used during operation
* @param encoder {@code DBEncoder} to be used
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/insert-documents/ Insert Documents
*/
public WriteResult insert(final DBObject[] documents, final WriteConcern aWriteConcern, final DBEncoder encoder) {
return insert(asList(documents), aWriteConcern, encoder);
}
/**
* Insert documents into a collection. If the collection does not exists on the server, then it will be created. If the new document
* does not contain an '_id' field, it will be added.
*
* @param documents a list of {@code DBObject}'s to be inserted
* @param aWriteConcern {@code WriteConcern} to be used during operation
* @param dbEncoder {@code DBEncoder} to be used
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/insert-documents/ Insert Documents
*/
public WriteResult insert(final List documents, final WriteConcern aWriteConcern,
@Nullable final DBEncoder dbEncoder) {
return insert(documents, new InsertOptions().writeConcern(aWriteConcern).dbEncoder(dbEncoder));
}
/**
* Insert documents into a collection. If the collection does not exists on the server, then it will be created. If the new document
* does not contain an '_id' field, it will be added.
*
* If the value of the continueOnError property of the given {@code InsertOptions} is true,
* that value will override the value of the continueOnError property of the given {@code WriteConcern}. Otherwise,
* the value of the continueOnError property of the given {@code WriteConcern} will take effect.
*
* @param documents a list of {@code DBObject}'s to be inserted
* @param insertOptions the options to use for the insert
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/insert-documents/ Insert Documents
*/
public WriteResult insert(final List documents, final InsertOptions insertOptions) {
WriteConcern writeConcern = insertOptions.getWriteConcern() != null ? insertOptions.getWriteConcern() : getWriteConcern();
Encoder encoder = toEncoder(insertOptions.getDbEncoder());
List insertRequestList = new ArrayList(documents.size());
for (DBObject cur : documents) {
if (cur.get(ID_FIELD_NAME) == null) {
cur.put(ID_FIELD_NAME, new ObjectId());
}
insertRequestList.add(new InsertRequest(new BsonDocumentWrapper(cur, encoder)));
}
return insert(insertRequestList, writeConcern, insertOptions.isContinueOnError(), insertOptions.getBypassDocumentValidation());
}
private Encoder toEncoder(@Nullable final DBEncoder dbEncoder) {
return dbEncoder != null ? new DBEncoderAdapter(dbEncoder) : objectCodec;
}
private WriteResult insert(final List insertRequestList, final WriteConcern writeConcern,
final boolean continueOnError, @Nullable final Boolean bypassDocumentValidation) {
return executeWriteOperation(new InsertOperation(getNamespace(), !continueOnError, writeConcern, retryWrites, insertRequestList)
.bypassDocumentValidation(bypassDocumentValidation));
}
WriteResult executeWriteOperation(final BaseWriteOperation operation) {
return translateWriteResult(executor.execute(operation, getReadConcern()));
}
private WriteResult translateWriteResult(final WriteConcernResult writeConcernResult) {
if (!writeConcernResult.wasAcknowledged()) {
return WriteResult.unacknowledged();
}
return translateWriteResult(writeConcernResult.getCount(), writeConcernResult.isUpdateOfExisting(),
writeConcernResult.getUpsertedId());
}
private WriteResult translateWriteResult(final int count, final boolean isUpdateOfExisting, @Nullable final BsonValue upsertedId) {
Object newUpsertedId = upsertedId == null
? null
: getObjectCodec().decode(new BsonDocumentReader(new BsonDocument("_id", upsertedId)),
DecoderContext.builder().build())
.get("_id");
return new WriteResult(count, isUpdateOfExisting, newUpsertedId);
}
/**
* Update an existing document or insert a document depending on the parameter. If the document does not contain an '_id' field, then
* the method performs an insert with the specified fields in the document as well as an '_id' field with a unique objectId value. If
* the document contains an '_id' field, then the method performs an upsert querying the collection on the '_id' field:
*
* - If a document does not exist with the specified '_id' value, the method performs an insert with the specified fields in
* the document.
* - If a document exists with the specified '_id' value, the method performs an update,
* replacing all field in the existing record with the fields from the document.
*
*
* @param document {@link DBObject} to save to the collection.
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert or update command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/modify-documents/#modify-a-document-with-save-method Save
*/
public WriteResult save(final DBObject document) {
return save(document, getWriteConcern());
}
/**
* Update an existing document or insert a document depending on the parameter. If the document does not contain an '_id' field, then
* the method performs an insert with the specified fields in the document as well as an '_id' field with a unique objectId value. If
* the document contains an '_id' field, then the method performs an upsert querying the collection on the '_id' field:
*
* - If a document does not exist with the specified '_id' value, the method performs an insert with the specified fields in
* the document.
* - If a document exists with the specified '_id' value, the method performs an update,
* replacing all field in the existing record with the fields from the document.
*
*
* @param document {@link DBObject} to save to the collection.
* @param writeConcern {@code WriteConcern} to be used during operation
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the insert or update command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/modify-documents/#modify-a-document-with-save-method Save
*/
public WriteResult save(final DBObject document, final WriteConcern writeConcern) {
Object id = document.get(ID_FIELD_NAME);
if (id == null) {
return insert(document, writeConcern);
} else {
return replaceOrInsert(document, id, writeConcern);
}
}
private WriteResult replaceOrInsert(final DBObject obj, final Object id, final WriteConcern writeConcern) {
DBObject filter = new BasicDBObject(ID_FIELD_NAME, id);
UpdateRequest replaceRequest = new UpdateRequest(wrap(filter), wrap(obj, objectCodec),
com.mongodb.bulk.WriteRequest.Type.REPLACE).upsert(true);
return executeWriteOperation(new UpdateOperation(getNamespace(), false, writeConcern, retryWrites,
singletonList(replaceRequest)));
}
/**
* Modify an existing document or documents in collection. The query parameter employs the same query selectors, as used in {@code
* find()}.
*
* @param query the selection criteria for the update
* @param update the modifications to apply
* @param upsert when true, inserts a document if no document matches the update query criteria
* @param multi when true, updates all documents in the collection that match the update query criteria, otherwise only updates
* one
* @param aWriteConcern {@code WriteConcern} to be used during operation
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/modify-documents/ Modify Documents
*/
public WriteResult update(final DBObject query, final DBObject update, final boolean upsert, final boolean multi,
final WriteConcern aWriteConcern) {
return update(query, update, upsert, multi, aWriteConcern, null);
}
/**
* Modify an existing document or documents in collection. By default the method updates a single document. The query parameter employs
* the same query selectors, as used in {@code find()}.
*
* @param query the selection criteria for the update
* @param update the modifications to apply
* @param upsert when true, inserts a document if no document matches the update query criteria
* @param multi when true, updates all documents in the collection that match the update query criteria, otherwise only updates
* one
* @param concern {@code WriteConcern} to be used during operation
* @param encoder {@code DBEncoder} to be used
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/modify-documents/ Modify Documents
*/
public WriteResult update(final DBObject query, final DBObject update, final boolean upsert, final boolean multi,
final WriteConcern concern, @Nullable final DBEncoder encoder) {
return update(query, update, upsert, multi, concern, null, encoder);
}
/**
* Modify an existing document or documents in collection. By default the method updates a single document. The query parameter employs
* the same query selectors, as used in {@link DBCollection#find(DBObject)}.
*
* @param query the selection criteria for the update
* @param update the modifications to apply
* @param upsert when true, inserts a document if no document matches the update query criteria
* @param multi when true, updates all documents in the collection that match the update query criteria, otherwise only updates one
* @param concern {@code WriteConcern} to be used during operation
* @param bypassDocumentValidation whether to bypass document validation.
* @param encoder the DBEncoder to use
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/modify-documents/ Modify
* @since 2.14
*/
public WriteResult update(final DBObject query, final DBObject update, final boolean upsert, final boolean multi,
final WriteConcern concern, @Nullable final Boolean bypassDocumentValidation,
@Nullable final DBEncoder encoder) {
return update(query, update, new DBCollectionUpdateOptions().upsert(upsert).multi(multi)
.writeConcern(concern).bypassDocumentValidation(bypassDocumentValidation).encoder(encoder));
}
/**
* Modify an existing document or documents in collection. The query parameter employs the same query selectors, as used in {@code
* find()}.
*
* @param query the selection criteria for the update
* @param update the modifications to apply
* @param upsert when true, inserts a document if no document matches the update query criteria
* @param multi when true, updates all documents in the collection that match the update query criteria, otherwise only updates one
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/modify-documents/ Modify Documents
*/
public WriteResult update(final DBObject query, final DBObject update, final boolean upsert, final boolean multi) {
return update(query, update, upsert, multi, getWriteConcern());
}
/**
* Modify an existing document. The query parameter employs the same query selectors, as used in {@code find()}.
*
* @param query the selection criteria for the update
* @param update the modifications to apply
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/modify-documents/ Modify Documents
*/
public WriteResult update(final DBObject query, final DBObject update) {
return update(query, update, false, false);
}
/**
* Modify documents in collection. The query parameter employs the same query selectors, as used in {@code find()}.
*
* @param query the selection criteria for the update
* @param update the modifications to apply
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/modify-documents/ Modify Documents
*/
public WriteResult updateMulti(final DBObject query, final DBObject update) {
return update(query, update, false, true);
}
/**
* Modify an existing document or documents in collection.
*
* @param query the selection criteria for the update
* @param update the modifications to apply
* @param options the options to apply to the update operation
* @return the result of the operation
* @throws com.mongodb.DuplicateKeyException if the write failed to a duplicate unique key
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/modify-documents/ Modify
* @since 3.4
*/
public WriteResult update(final DBObject query, final DBObject update, final DBCollectionUpdateOptions options) {
notNull("query", query);
notNull("update", update);
notNull("options", options);
WriteConcern writeConcern = options.getWriteConcern() != null ? options.getWriteConcern() : getWriteConcern();
com.mongodb.bulk.WriteRequest.Type updateType = !update.keySet().isEmpty() && update.keySet().iterator().next().startsWith("$")
? com.mongodb.bulk.WriteRequest.Type.UPDATE
: com.mongodb.bulk.WriteRequest.Type.REPLACE;
UpdateRequest updateRequest = new UpdateRequest(wrap(query), wrap(update, options.getEncoder()), updateType)
.upsert(options.isUpsert()).multi(options.isMulti())
.collation(options.getCollation())
.arrayFilters(wrapAllowNull(options.getArrayFilters(), options.getEncoder()));
return executeWriteOperation(new UpdateOperation(getNamespace(), true, writeConcern, retryWrites,
singletonList(updateRequest)).bypassDocumentValidation(options.getBypassDocumentValidation()));
}
/**
* Remove documents from a collection.
*
* @param query the deletion criteria using query operators. Omit the query parameter or pass an empty document to delete all documents
* in the collection.
* @return the result of the operation
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the delete command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/remove-documents/ Remove Documents
*/
public WriteResult remove(final DBObject query) {
return remove(query, getWriteConcern());
}
/**
* Remove documents from a collection.
*
* @param query the deletion criteria using query operators. Omit the query parameter or pass an empty document to delete all
* documents in the collection.
* @param writeConcern {@code WriteConcern} to be used during operation
* @return the result of the operation
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the delete command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/remove-documents/ Remove Documents
*/
public WriteResult remove(final DBObject query, final WriteConcern writeConcern) {
return remove(query, new DBCollectionRemoveOptions().writeConcern(writeConcern));
}
/**
* Remove documents from a collection.
*
* @param query the deletion criteria using query operators. Omit the query parameter or pass an empty document to delete all
* documents in the collection.
* @param writeConcern {@code WriteConcern} to be used during operation
* @param encoder {@code DBEncoder} to be used
* @return the result of the operation
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the delete command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/remove-documents/ Remove Documents
*/
public WriteResult remove(final DBObject query, final WriteConcern writeConcern, final DBEncoder encoder) {
return remove(query, new DBCollectionRemoveOptions().writeConcern(writeConcern).encoder(encoder));
}
/**
* Remove documents from a collection.
*
* @param query the deletion criteria using query operators. Omit the query parameter or pass an empty document to delete all
* documents in the collection.
* @param options the options to apply to the delete operation
* @return the result of the operation
* @throws com.mongodb.WriteConcernException if the write failed due some other failure specific to the delete command
* @throws com.mongodb.MongoCommandException if the write failed due to a specific command exception
* @throws MongoException if the operation failed for some other reason
* @mongodb.driver.manual tutorial/remove-documents/ Remove Documents
* @since 3.4
*/
public WriteResult remove(final DBObject query, final DBCollectionRemoveOptions options) {
notNull("query", query);
notNull("options", options);
WriteConcern writeConcern = options.getWriteConcern() != null ? options.getWriteConcern() : getWriteConcern();
DeleteRequest deleteRequest = new DeleteRequest(wrap(query, options.getEncoder())).collation(options.getCollation());
return executeWriteOperation(new DeleteOperation(getNamespace(), false, writeConcern, retryWrites,
singletonList(deleteRequest)));
}
/**
* Select documents in collection and get a cursor to the selected documents.
*
* @param query the selection criteria using query operators. Omit the query parameter or pass an empty document to return all
* documents in the collection.
* @param projection specifies which fields MongoDB will return from the documents in the result set.
* @param numToSkip number of documents to skip
* @param batchSize see {@link DBCursor#batchSize(int)} for more information
* @param options query options to be used
* @return A cursor to the documents that match the query criteria
* @mongodb.driver.manual tutorial/query-documents/ Querying
* @deprecated use {@link com.mongodb.DBCursor#skip(int)}, {@link com.mongodb.DBCursor#batchSize(int)} and {@link
* com.mongodb.DBCursor#setOptions(int)} on the {@code DBCursor} returned from {@link com.mongodb.DBCollection#find(DBObject,
* DBObject)}
*/
@Deprecated
public DBCursor find(final DBObject query, final DBObject projection, final int numToSkip, final int batchSize,
final int options) {
return new DBCursor(this, query, projection, getReadPreference()).batchSize(batchSize).skip(numToSkip).setOptions(options);
}
/**
* Select documents in collection and get a cursor to the selected documents.
*
* @param query the selection criteria using query operators. Omit the query parameter or pass an empty document to return all
* documents in the collection.
* @param projection specifies which fields MongoDB will return from the documents in the result set.
* @param numToSkip number of documents to skip
* @param batchSize see {@link DBCursor#batchSize(int)} for more information
* @return A cursor to the documents that match the query criteria
* @mongodb.driver.manual tutorial/query-documents/ Querying
* @deprecated use {@link com.mongodb.DBCursor#skip(int)} and {@link com.mongodb.DBCursor#batchSize(int)} on the {@code DBCursor}
* returned from {@link com.mongodb.DBCollection#find(DBObject, DBObject)}
*/
@Deprecated
public DBCursor find(final DBObject query, final DBObject projection, final int numToSkip, final int batchSize) {
return new DBCursor(this, query, projection, getReadPreference()).batchSize(batchSize).skip(numToSkip);
}
/**
* Select documents in collection and get a cursor to the selected documents.
*
* @param query the selection criteria using query operators. Omit the query parameter or pass an empty document to return all documents
* in the collection.
* @return A cursor to the documents that match the query criteria
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
public DBCursor find(final DBObject query) {
return new DBCursor(this, query, null, getReadPreference());
}
/**
* Select documents in collection and get a cursor to the selected documents.
*
* @param query the selection criteria using query operators. Omit the query parameter or pass an empty document to return all
* documents in the collection.
* @param projection specifies which fields MongoDB will return from the documents in the result set.
* @return A cursor to the documents that match the query criteria
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
public DBCursor find(final DBObject query, final DBObject projection) {
return new DBCursor(this, query, projection, getReadPreference());
}
/**
* Select all documents in collection and get a cursor to the selected documents.
*
* @return A cursor to the documents that match the query criteria
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
public DBCursor find() {
return find(new BasicDBObject());
}
/**
* Select documents in collection and get a cursor to the selected documents.
*
* @param query the selection criteria using query operators. Omit the query parameter or pass an empty document to return all
* documents in the collection.
* @param options the options for the find operation.
* @return A cursor to the documents that match the query criteria
* @mongodb.driver.manual tutorial/query-documents/ Querying
* @since 3.4
*/
public DBCursor find(@Nullable final DBObject query, final DBCollectionFindOptions options) {
return new DBCursor(this, query, options);
}
/**
* Get a single document from collection.
*
* @return A document that satisfies the query specified as the argument to this method.
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
@Nullable
public DBObject findOne() {
return findOne(new BasicDBObject());
}
/**
* Get a single document from collection.
*
* @param query the selection criteria using query operators.
* @return A document that satisfies the query specified as the argument to this method.
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
@Nullable
public DBObject findOne(final DBObject query) {
return findOne(query, null, null, getReadPreference());
}
/**
* Get a single document from collection.
*
* @param query the selection criteria using query operators.
* @param projection specifies which fields MongoDB will return from the documents in the result set.
* @return A document that satisfies the query specified as the argument to this method.
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
@Nullable
public DBObject findOne(final DBObject query, final DBObject projection) {
return findOne(query, projection, null, getReadPreference());
}
/**
* Get a single document from collection.
*
* @param query the selection criteria using query operators.
* @param projection specifies which fields MongoDB will return from the documents in the result set.
* @param sort A document whose fields specify the attributes on which to sort the result set.
* @return A document that satisfies the query specified as the argument to this method.
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
@Nullable
public DBObject findOne(final DBObject query, final DBObject projection, final DBObject sort) {
return findOne(query, projection, sort, getReadPreference());
}
/**
* Get a single document from collection.
*
* @param query the selection criteria using query operators.
* @param projection specifies which fields MongoDB will return from the documents in the result set.
* @param readPreference {@link ReadPreference} to be used for this operation
* @return A document that satisfies the query specified as the argument to this method.
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
@Nullable
public DBObject findOne(final DBObject query, final DBObject projection, final ReadPreference readPreference) {
return findOne(query, projection, null, readPreference);
}
/**
* Get a single document from collection.
*
* @param query the selection criteria using query operators.
* @param projection specifies which projection MongoDB will return from the documents in the result set.
* @param sort A document whose fields specify the attributes on which to sort the result set.
* @param readPreference {@code ReadPreference} to be used for this operation
* @return A document that satisfies the query specified as the argument to this method.
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
@Nullable
public DBObject findOne(@Nullable final DBObject query, @Nullable final DBObject projection, @Nullable final DBObject sort,
final ReadPreference readPreference) {
return findOne(query != null ? query : new BasicDBObject(),
new DBCollectionFindOptions().projection(projection).sort(sort).readPreference(readPreference));
}
/**
* Get a single document from collection by '_id'.
*
* @param id value of '_id' field of a document we are looking for
* @return A document with '_id' provided as the argument to this method.
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
@Nullable
public DBObject findOne(final Object id) {
return findOne(new BasicDBObject("_id", id), new DBCollectionFindOptions());
}
/**
* Get a single document from collection by '_id'.
*
* @param id value of '_id' field of a document we are looking for
* @param projection specifies which projection MongoDB will return from the documents in the result set.
* @return A document that satisfies the query specified as the argument to this method.
* @mongodb.driver.manual tutorial/query-documents/ Querying
*/
@Nullable
public DBObject findOne(final Object id, final DBObject projection) {
return findOne(new BasicDBObject("_id", id), new DBCollectionFindOptions().projection(projection));
}
/**
* Get a single document from collection.
*
* @param query the selection criteria using query operators.
* @param findOptions the options for the find operation.
* @return A document that satisfies the query specified as the argument to this method.
* @mongodb.driver.manual tutorial/query-documents/ Querying
* @since 3.4
*/
@Nullable
public DBObject findOne(@Nullable final DBObject query, final DBCollectionFindOptions findOptions) {
return find(query, findOptions).one();
}
/**
* Same as {@link #getCount()}
*
* @return the number of documents in collection
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
*/
public long count() {
return getCount(new BasicDBObject(), new DBCollectionCountOptions());
}
/**
* Same as {@link #getCount(DBObject)}
*
* @param query specifies the selection criteria
* @return the number of documents that matches selection criteria
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
*/
public long count(@Nullable final DBObject query) {
return getCount(query, new DBCollectionCountOptions());
}
/**
* Get the count of documents in collection that would match a criteria.
*
* @param query specifies the selection criteria
* @param readPreference {@link ReadPreference} to be used for this operation
* @return the number of documents that matches selection criteria
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
*/
public long count(@Nullable final DBObject query, final ReadPreference readPreference) {
return getCount(query, null, readPreference);
}
/**
* Get the count of documents in collection that would match a criteria.
*
* @param query specifies the selection criteria
* @param options the options for the count operation.
* @return the number of documents that matches selection criteria
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
* @since 3.4
*/
public long count(@Nullable final DBObject query, final DBCollectionCountOptions options) {
return getCount(query, options);
}
/**
* Get the count of documents in collection.
*
* @return the number of documents in collection
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
*/
public long getCount() {
return getCount(new BasicDBObject(), new DBCollectionCountOptions());
}
/**
* Get the count of documents in collection.
*
* @param readPreference {@link ReadPreference} to be used for this operation
* @return the number of documents in collection
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
*/
public long getCount(final ReadPreference readPreference) {
return getCount(new BasicDBObject(), null, readPreference);
}
/**
* Get the count of documents in collection that would match a criteria.
*
* @param query specifies the selection criteria
* @return the number of documents that matches selection criteria
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
*/
public long getCount(@Nullable final DBObject query) {
return getCount(query, new DBCollectionCountOptions());
}
/**
* Get the count of documents in collection that would match a criteria.
*
* @param query specifies the selection criteria
* @param projection this is ignored
* @return the number of documents that matches selection criteria
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
* @deprecated Prefer {@link #count(DBObject, DBCollectionCountOptions)}
*/
@Deprecated
public long getCount(@Nullable final DBObject query, final DBObject projection) {
return getCount(query, projection, 0, 0);
}
/**
* Get the count of documents in collection that would match a criteria.
*
* @param query specifies the selection criteria
* @param projection this is ignored
* @param readPreference {@link ReadPreference} to be used for this operation
* @return the number of documents that matches selection criteria
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
* @deprecated Prefer {@link #count(DBObject, DBCollectionCountOptions)}
*/
@Deprecated
public long getCount(@Nullable final DBObject query, @Nullable final DBObject projection, final ReadPreference readPreference) {
return getCount(query, projection, 0, 0, readPreference);
}
/**
* Get the count of documents in collection that would match a criteria.
*
* @param query specifies the selection criteria
* @param projection this is ignored
* @param limit limit the count to this value
* @param skip number of documents to skip
* @return the number of documents that matches selection criteria
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
* @deprecated Prefer {@link #count(DBObject, DBCollectionCountOptions)}
*/
@Deprecated
public long getCount(@Nullable final DBObject query, @Nullable final DBObject projection, final long limit, final long skip) {
return getCount(query, projection, limit, skip, getReadPreference());
}
/**
* Get the count of documents in collection that would match a criteria.
*
* @param query specifies the selection criteria
* @param projection this is ignored
* @param limit limit the count to this value
* @param skip number of documents to skip
* @param readPreference {@link ReadPreference} to be used for this operation
* @return the number of documents that matches selection criteria
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
* @deprecated Prefer {@link #count(DBObject, DBCollectionCountOptions)}
*/
@Deprecated
public long getCount(@Nullable final DBObject query, @Nullable final DBObject projection, final long limit, final long skip,
final ReadPreference readPreference) {
return getCount(query, new DBCollectionCountOptions().limit(limit).skip(skip).readPreference(readPreference));
}
/**
* Get the count of documents in collection that would match a criteria.
*
* @param query specifies the selection criteria
* @param options the options for the count operation.
* @return the number of documents that matches selection criteria
* @throws MongoException if the operation failed
* @mongodb.driver.manual reference/command/count/ Count
* @since 3.4
*/
public long getCount(@Nullable final DBObject query, final DBCollectionCountOptions options) {
notNull("countOptions", options);
CountOperation operation = new CountOperation(getNamespace())
.skip(options.getSkip())
.limit(options.getLimit())
.maxTime(options.getMaxTime(MILLISECONDS), MILLISECONDS)
.collation(options.getCollation())
.retryReads(retryReads);
if (query != null) {
operation.filter(wrap(query));
}
DBObject hint = options.getHint();
if (hint != null) {
operation.hint(wrap(hint));
} else {
String hintString = options.getHintString();
if (hintString != null) {
operation.hint(new BsonString(hintString));
}
}
ReadPreference optionsReadPreference = options.getReadPreference();
ReadConcern optionsReadConcern = options.getReadConcern();
return executor.execute(operation, optionsReadPreference != null ? optionsReadPreference : getReadPreference(),
optionsReadConcern != null ? optionsReadConcern : getReadConcern());
}
/**
* Change the name of an existing collection.
*
* @param newName specifies the new name of the collection
* @return the collection with new name
* @throws MongoException if newName is the name of an existing collection.
* @mongodb.driver.manual reference/command/renameCollection/ Rename Collection
*/
public DBCollection rename(final String newName) {
return rename(newName, false);
}
/**
* Change the name of an existing collection.
*
* @param newName specifies the new name of the collection
* @param dropTarget If {@code true}, mongod will drop the collection with the target name if it exists
* @return the collection with new name
* @throws MongoException if target is the name of an existing collection and {@code dropTarget=false}.
* @mongodb.driver.manual reference/command/renameCollection/ Rename Collection
*/
public DBCollection rename(final String newName, final boolean dropTarget) {
try {
executor.execute(new RenameCollectionOperation(getNamespace(),
new MongoNamespace(getNamespace().getDatabaseName(), newName), getWriteConcern())
.dropTarget(dropTarget), getReadConcern());
return getDB().getCollection(newName);
} catch (MongoWriteConcernException e) {
throw createWriteConcernException(e);
}
}
/**
* Group documents in a collection by the specified key and performs simple aggregation functions such as computing counts and sums.
* This is analogous to a {@code SELECT ... GROUP BY} statement in SQL.
*
* @param key specifies one or more document fields to group
* @param cond specifies the selection criteria to determine which documents in the collection to process
* @param initial initializes the aggregation result document
* @param reduce specifies an $reduce function, that operates on the documents during the grouping operation
* @return a document with the grouped records as well as the command meta-data
* @mongodb.driver.manual reference/command/group/ Group Command
* @deprecated The group command was deprecated in MongoDB 3.4
*/
@Deprecated
public DBObject group(final DBObject key, final DBObject cond, final DBObject initial, final String reduce) {
return group(key, cond, initial, reduce, null);
}
/**
* Group documents in a collection by the specified key and performs simple aggregation functions such as computing counts and sums.
* This is analogous to a {@code SELECT ... GROUP BY} statement in SQL.
*
* @param key specifies one or more document fields to group
* @param cond specifies the selection criteria to determine which documents in the collection to process
* @param initial initializes the aggregation result document
* @param reduce specifies an $reduce Javascript function, that operates on the documents during the grouping operation
* @param finalize specifies a Javascript function that runs each item in the result set before final value will be returned
* @return a document with the grouped records as well as the command meta-data
* @mongodb.driver.manual reference/command/group/ Group Command
* @deprecated The group command was deprecated in MongoDB 3.4
*/
@Deprecated
public DBObject group(final DBObject key, final DBObject cond, final DBObject initial, final String reduce,
@Nullable final String finalize) {
return group(key, cond, initial, reduce, finalize, getReadPreference());
}
/**
* Group documents in a collection by the specified key and performs simple aggregation functions such as computing counts and sums.
* This is analogous to a {@code SELECT ... GROUP BY} statement in SQL.
*
* @param key specifies one or more document fields to group
* @param cond specifies the selection criteria to determine which documents in the collection to process
* @param initial initializes the aggregation result document
* @param reduce specifies an $reduce Javascript function, that operates on the documents during the grouping operation
* @param finalize specifies a Javascript function that runs each item in the result set before final value will be returned
* @param readPreference {@link ReadPreference} to be used for this operation
* @return a document with the grouped records as well as the command meta-data
* @mongodb.driver.manual reference/command/group/ Group Command
* @deprecated The group command was deprecated in MongoDB 3.4
*/
@Deprecated
public DBObject group(final DBObject key, final DBObject cond, final DBObject initial, final String reduce,
@Nullable final String finalize, final ReadPreference readPreference) {
return group(new GroupCommand(this, key, cond, initial, reduce, finalize), readPreference);
}
/**
* Group documents in a collection by the specified key and performs simple aggregation functions such as computing counts and sums.
* This is analogous to a {@code SELECT ... GROUP BY} statement in SQL.
*
* @param cmd the group command
* @return a document with the grouped records as well as the command meta-data
* @mongodb.driver.manual reference/command/group/ Group Command
* @deprecated The group command was deprecated in MongoDB 3.4
*/
@Deprecated
public DBObject group(final GroupCommand cmd) {
return group(cmd, getReadPreference());
}
/**
* Group documents in a collection by the specified key and performs simple aggregation functions such as computing counts and sums.
* This is analogous to a {@code SELECT ... GROUP BY} statement in SQL.
*
* @param cmd the group command
* @param readPreference {@link ReadPreference} to be used for this operation
* @return a document with the grouped records as well as the command meta-data
* @mongodb.driver.manual reference/command/group/ Group Command
* @deprecated The group command was deprecated in MongoDB 3.4
*/
@Deprecated
public DBObject group(final GroupCommand cmd, final ReadPreference readPreference) {
return toDBList(executor.execute(cmd.toOperation(getNamespace(), getDefaultDBObjectCodec(), retryReads), readPreference,
getReadConcern()));
}
/**
* Find the distinct values for a specified field across a collection and returns the results in an array.
*
* @param fieldName Specifies the field for which to return the distinct values.
* @return a List of the distinct values
* @mongodb.driver.manual reference/command/distinct Distinct Command
*/
public List distinct(final String fieldName) {
return distinct(fieldName, getReadPreference());
}
/**
* Find the distinct values for a specified field across a collection and returns the results in an array.
*
* @param fieldName Specifies the field for which to return the distinct values
* @param readPreference {@link ReadPreference} to be used for this operation
* @return a List of the distinct values
* @mongodb.driver.manual reference/command/distinct Distinct Command
*/
public List distinct(final String fieldName, final ReadPreference readPreference) {
return distinct(fieldName, new BasicDBObject(), readPreference);
}
/**
* Find the distinct values for a specified field across a collection and returns the results in an array.
*
* @param fieldName Specifies the field for which to return the distinct values
* @param query specifies the selection query to determine the subset of documents from which to retrieve the distinct values
* @return an array of the distinct values
* @mongodb.driver.manual reference/command/distinct Distinct Command
*/
public List distinct(final String fieldName, final DBObject query) {
return distinct(fieldName, query, getReadPreference());
}
/**
* Find the distinct values for a specified field across a collection and returns the results in an array.
*
* @param fieldName Specifies the field for which to return the distinct values
* @param query specifies the selection query to determine the subset of documents from which to retrieve the distinct values
* @param readPreference {@link ReadPreference} to be used for this operation
* @return A {@code List} of the distinct values
* @mongodb.driver.manual reference/command/distinct Distinct Command
*/
public List distinct(final String fieldName, final DBObject query, final ReadPreference readPreference) {
return distinct(fieldName, new DBCollectionDistinctOptions().filter(query).readPreference(readPreference));
}
/**
* Find the distinct values for a specified field across a collection and returns the results in an array.
*
* @param fieldName Specifies the field for which to return the distinct values
* @param options the options to apply for this operation
* @return A {@code List} of the distinct values
* @mongodb.driver.manual reference/command/distinct Distinct Command
* @since 3.4
*/
public List distinct(final String fieldName, final DBCollectionDistinctOptions options) {
notNull("fieldName", fieldName);
return new MongoIterableImpl(null, executor,
options.getReadConcern() != null ? options.getReadConcern() : getReadConcern(),
options.getReadPreference() != null ? options.getReadPreference() : getReadPreference(),
retryReads) {
@Override
public ReadOperation> asReadOperation() {
return new DistinctOperation(getNamespace(), fieldName, new BsonValueCodec())
.filter(wrapAllowNull(options.getFilter()))
.collation(options.getCollation())
.retryReads(retryReads);
}
}.map(new Function() {
@Override
public Object apply(final BsonValue bsonValue) {
if (bsonValue == null) {
return null;
}
BsonDocument document = new BsonDocument("value", bsonValue);
DBObject obj = getDefaultDBObjectCodec().decode(new BsonDocumentReader(document), DecoderContext.builder().build());
return obj.get("value");
}
}).into(new ArrayList