driver-legacy/src/main/com/mongodb/DBCollection.java
public DBObject findAndModify(final DBObject query, final DBCollectionFindAndModifyOptions options) {
        notNull("query", query);
        notNull("options", options);
        WriteConcern optionsWriteConcern = options.getWriteConcern();
        WriteConcern writeConcern = optionsWriteConcern != null ? optionsWriteConcern : getWriteConcern();
        WriteOperation<DBObject> operation;
        if (options.isRemove()) {
            operation = new FindAndDeleteOperation<DBObject>(getNamespace(), writeConcern, retryWrites, objectCodec)
                        .filter(wrapAllowNull(query))
                        .projection(wrapAllowNull(options.getProjection()))
                        .sort(wrapAllowNull(options.getSort()))
                        .maxTime(options.getMaxTime(MILLISECONDS), MILLISECONDS)
                        .collation(options.getCollation());
        } else {
            DBObject update = options.getUpdate();
            if (update == null) {
                throw new IllegalArgumentException("update can not be null unless it's a remove");
            }
            if (!update.keySet().isEmpty() && update.keySet().iterator().next().charAt(0) == '$') {
                operation = new FindAndUpdateOperation<DBObject>(getNamespace(), writeConcern, retryWrites, objectCodec,
                        wrap(update))
                        .filter(wrap(query))
                        .projection(wrapAllowNull(options.getProjection()))
                        .sort(wrapAllowNull(options.getSort()))
                        .returnOriginal(!options.returnNew())
                        .upsert(options.isUpsert())
                        .maxTime(options.getMaxTime(MILLISECONDS), MILLISECONDS)
                        .bypassDocumentValidation(options.getBypassDocumentValidation())
                        .collation(options.getCollation())
                        .arrayFilters(wrapAllowNull(options.getArrayFilters(), (Encoder<DBObject>) null));
            } else {
                operation = new FindAndReplaceOperation<DBObject>(getNamespace(), writeConcern, retryWrites, objectCodec,
                        wrap(update))
                        .filter(wrap(query))
                        .projection(wrapAllowNull(options.getProjection()))
                        .sort(wrapAllowNull(options.getSort()))
                        .returnOriginal(!options.returnNew())
                        .upsert(options.isUpsert())
                        .maxTime(options.getMaxTime(MILLISECONDS), MILLISECONDS)
                        .bypassDocumentValidation(options.getBypassDocumentValidation())
                        .collation(options.getCollation());
            }
        }

        try {
            return executor.execute(operation, getReadConcern());
        } catch (MongoWriteConcernException e) {
            throw createWriteConcernException(e);
        }
    }
public DBObject findAndModify(final DBObject query, final DBCollectionFindAndModifyOptions options) {
        notNull("query", query);
        notNull("options", options);
        WriteConcern optionsWriteConcern = options.getWriteConcern();
        WriteConcern writeConcern = optionsWriteConcern != null ? optionsWriteConcern : getWriteConcern();
        WriteOperation<DBObject> operation;
        if (options.isRemove()) {
            operation = new FindAndDeleteOperation<DBObject>(getNamespace(), writeConcern, retryWrites, objectCodec)
                        .filter(wrapAllowNull(query))
                        .projection(wrapAllowNull(options.getProjection()))
                        .sort(wrapAllowNull(options.getSort()))
                        .maxTime(options.getMaxTime(MILLISECONDS), MILLISECONDS)
                        .collation(options.getCollation());
        } else {
            DBObject update = options.getUpdate();
            if (update == null) {
                throw new IllegalArgumentException("update can not be null unless it's a remove");
            }
            if (!update.keySet().isEmpty() && update.keySet().iterator().next().charAt(0) == '$') {
                operation = new FindAndUpdateOperation<DBObject>(getNamespace(), writeConcern, retryWrites, objectCodec,
                        wrap(update))
                        .filter(wrap(query))
                        .projection(wrapAllowNull(options.getProjection()))
                        .sort(wrapAllowNull(options.getSort()))
                        .returnOriginal(!options.returnNew())
                        .upsert(options.isUpsert())
                        .maxTime(options.getMaxTime(MILLISECONDS), MILLISECONDS)
                        .bypassDocumentValidation(options.getBypassDocumentValidation())
                        .collation(options.getCollation())
                        .arrayFilters(wrapAllowNull(options.getArrayFilters(), (Encoder<DBObject>) null));
            } else {
                operation = new FindAndReplaceOperation<DBObject>(getNamespace(), writeConcern, retryWrites, objectCodec,
                        wrap(update))
                        .filter(wrap(query))
                        .projection(wrapAllowNull(options.getProjection()))
                        .sort(wrapAllowNull(options.getSort()))
                        .returnOriginal(!options.returnNew())
                        .upsert(options.isUpsert())
                        .maxTime(options.getMaxTime(MILLISECONDS), MILLISECONDS)
                        .bypassDocumentValidation(options.getBypassDocumentValidation())
                        .collation(options.getCollation());
            }
        }

        try {
            return executor.execute(operation, getReadConcern());
        } catch (MongoWriteConcernException e) {
            throw createWriteConcernException(e);
        }
    }
public DBObject findAndModify ( final DBObject query , final DBCollectionFindAndModifyOptions options ) { notNull ( "query" , query ) ; notNull ( "options" , options ) ; WriteConcern optionsWriteConcern = options . getWriteConcern ( ) ; WriteConcern writeConcern = optionsWriteConcern != null ? optionsWriteConcern : getWriteConcern ( ) ; WriteOperation < DBObject > operation ; if ( options . isRemove ( ) ) { operation = new FindAndDeleteOperation < DBObject > ( getNamespace ( ) , writeConcern , retryWrites , objectCodec ) . filter ( wrapAllowNull ( query ) ) . projection ( wrapAllowNull ( options . getProjection ( ) ) ) . sort ( wrapAllowNull ( options . getSort ( ) ) ) . maxTime ( options . getMaxTime ( MILLISECONDS ) , MILLISECONDS ) . collation ( options . getCollation ( ) ) ; } else { DBObject update = options . getUpdate ( ) ; if ( update == null ) { throw new IllegalArgumentException ( "update can not be null unless it's a remove" ) ; } if ( ! update . keySet ( ) . isEmpty ( ) && update . keySet ( ) . iterator ( ) . next ( ) . charAt ( 0 ) == ' ' ) { operation = new FindAndUpdateOperation < DBObject > ( getNamespace ( ) , writeConcern , retryWrites , objectCodec , wrap ( update ) ) . filter ( wrap ( query ) ) . projection ( wrapAllowNull ( options . getProjection ( ) ) ) . sort ( wrapAllowNull ( options . getSort ( ) ) ) . returnOriginal ( ! options . returnNew ( ) ) . upsert ( options . isUpsert ( ) ) . maxTime ( options . getMaxTime ( MILLISECONDS ) , MILLISECONDS ) . bypassDocumentValidation ( options . getBypassDocumentValidation ( ) ) . collation ( options . getCollation ( ) ) . arrayFilters ( wrapAllowNull ( options . getArrayFilters ( ) , ( Encoder < DBObject > ) null ) ) ; } else { operation = new FindAndReplaceOperation < DBObject > ( getNamespace ( ) , writeConcern , retryWrites , objectCodec , wrap ( update ) ) . filter ( wrap ( query ) ) . projection ( wrapAllowNull ( options . getProjection ( ) ) ) . sort ( wrapAllowNull ( options . getSort ( ) ) ) . returnOriginal ( ! options . returnNew ( ) ) . upsert ( options . isUpsert ( ) ) . maxTime ( options . getMaxTime ( MILLISECONDS ) , MILLISECONDS ) . bypassDocumentValidation ( options . getBypassDocumentValidation ( ) ) . collation ( options . getCollation ( ) ) ; } } try { return executor . execute ( operation , getReadConcern ( ) ) ; } catch ( MongoWriteConcernException e ) { throw createWriteConcernException ( e ) ; } }
Atomically modify and return a single document. By default, the returned document does not include the modifications made on the
update.

@param query    specifies the selection criteria for the modification
@param options  the options regarding the find and modify operation
@return the document as it was before the modifications, unless {@code oprtions.returnNew} is true, in which case it returns the
document after the changes were made
@throws WriteConcernException if the write failed due some other failure specific to the update command
@throws MongoException if the operation failed for some other reason
@mongodb.driver.manual reference/command/findAndModify/ Find and Modify
@since 3.4
Atomically modify and return a single document . By default the returned document does not include the modifications made on the update .