private void initializeClusterInstanceVersion() { String databaseName = CommonUtils.getApplication(this.endpoint).replaceAll("\\W", "_"); MongoDatabase database = this.mongoClient.getDatabase(databaseName); MongoCollection<Document> instances = database.getCollection(CONSTANTS_TB_INSTS); Bson condition = Filters.eq("_id", this.endpoint); Document increases = new Document(); increases.append("version", 1L); Document document = new Document(); document.append("$inc", increases); FindOneAndUpdateOptions options = new FindOneAndUpdateOptions(); options.upsert(true); Document target = instances.findOneAndUpdate(condition, document, new FindOneAndUpdateOptions().upsert(true)); this.instanceVersion = (target == null) ? 1 : (target.getLong("version") + 1); }
private FindOneAndUpdateOptions convertToFindOneAndUpdateOptions(FindAndModifyOptions options, Document fields, Document sort) { FindOneAndUpdateOptions result = new FindOneAndUpdateOptions(); result = result.projection(fields).sort(sort).upsert(options.isUpsert()); if (options.isReturnNew()) { result = result.returnDocument(ReturnDocument.AFTER); } else { result = result.returnDocument(ReturnDocument.BEFORE); } result = options.getCollation().map(Collation::toMongoCollation).map(result::collation).orElse(result); return result; } }
/** * Performs an upsert. If query will match a document, then it will be modified and old or new * version of document returned (depending if {@link #returningNew()} was configured). When * there * isn't any such matching document, a new one will be created and returned if * {@link #returningNew()} was configured. * <p> * <em>Note: Upsert operation requires special care to set or init all required attributes * (including but not limited to '_id'), so that valid document could be inserted into collection. * </em> * @return future of optional document. * */ public final FluentFuture<Optional<T>> upsert() { options.upsert(true); options.sort(convertToBson(ordering)); // TODO exclusion / projection return repository.doModify(criteria, collectRequiredUpdate(), options); }
public Document doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException { FindOneAndUpdateOptions opts = new FindOneAndUpdateOptions(); opts.sort(sort); if (options.isUpsert()) { opts.upsert(true); } opts.projection(fields); if (options.isReturnNew()) { opts.returnDocument(ReturnDocument.AFTER); } options.getCollation().map(Collation::toMongoCollation).ifPresent(opts::collation); return collection.findOneAndUpdate(query, update, opts); } }
private FindOneAndUpdateOptions convertToFindOneAndUpdateOptions(FindAndModifyOptions options, Document fields, Document sort) { FindOneAndUpdateOptions result = new FindOneAndUpdateOptions(); result = result.projection(fields).sort(sort).upsert(options.isUpsert()); if (options.isReturnNew()) { result = result.returnDocument(ReturnDocument.AFTER); } else { result = result.returnDocument(ReturnDocument.BEFORE); } result = options.getCollation().map(Collation::toMongoCollation).map(result::collation).orElse(result); return result; } }
public Document doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException { FindOneAndUpdateOptions opts = new FindOneAndUpdateOptions(); opts.sort(sort); if (options.isUpsert()) { opts.upsert(true); } opts.projection(fields); if (options.isReturnNew()) { opts.returnDocument(ReturnDocument.AFTER); } options.getCollation().map(Collation::toMongoCollation).ifPresent(opts::collation); return collection.findOneAndUpdate(query, update, opts); } }
private int getNextValueInSeq(final String counterName, final int numbers) { return MongoDbOperations.doDbOperation(() -> { Document andModify = counters.findOneAndUpdate(new Document("_id", counterName), new Document("$inc", new Document("seq", numbers)),new FindOneAndUpdateOptions().upsert(true).returnDocument(ReturnDocument.AFTER).projection(new Document("seq",1))); return (Integer) andModify.get("seq"); }); }
Document query = new Document("id", 2); Document setOnInsert = new Document(); setOnInsert.put("date", new Date()); setOnInsert.put("reptype", "EOD"); Document update = new Document("$setOnInsert", setOnInsert); FindOneAndUpdateOptions options = new FindOneAndUpdateOptions(); options.returnDocument(ReturnDocument.AFTER); options.upsert(true); db.getCollection("COL1").findOneAndUpdate(query, update, options);
@Nonnull @Override public <V> Optional<V> valueFor(SingleFeatureBean feature, V value) { checkNotNull(feature, "feature"); checkNotNull(value, "value"); final String ownerId = idConverter.convert(feature.owner()); final String featureId = Integer.toString(feature.id()); final String fieldName = concat(ModelDocument.F_SINGLE_FEATURE, featureId); final Bson filter = eq(ModelDocument.F_ID, ownerId); final Bson projection = include(fieldName); final Bson update = set(fieldName, serializeValue(value)); final ModelDocument instance = documents.findOneAndUpdate(filter, update, new FindOneAndUpdateOptions().upsert(true).projection(projection)); return Optional.ofNullable(instance) .map(ModelDocument::getSingleFeatures) .map(l -> l.get(featureId)) .map(this::deserializeValue); }
/** * Performs an upsert. If query will match a document, then it will be modified and old or new * version of document returned (depending if {@link #returningNew()} was configured). When * there * isn't any such matching document, a new one will be created and returned if * {@link #returningNew()} was configured. * <p> * <em>Note: Upsert operation requires special care to set or init all required attributes * (including but not limited to '_id'), so that valid document could be inserted into collection. * </em> * @return future of optional document. * */ public final FluentFuture<Optional<T>> upsert() { options.upsert(true); options.sort(convertToBson(ordering)); // TODO exclusion / projection return repository.doModify(criteria, collectRequiredUpdate(), options); }
@Override public void set(String aCounterName, long aValue) { collection .findOneAndUpdate( eq("_id", aCounterName), combine( Updates.set(DSL.VALUE, aValue), setOnInsert("_id", aCounterName), setOnInsert(DSL.CREATE_TIME, new Date()) ), new FindOneAndUpdateOptions() .upsert(true) ); }
@Test public void testFindOneAndUpdateUpsert() { Document result = collection.findOneAndUpdate(json("_id: 1"), json("$inc: {a: 1}"), new FindOneAndUpdateOptions().upsert(true).returnDocument(ReturnDocument.AFTER)); assertThat(result).isEqualTo(json("_id: 1, a: 1")); assertThat(collection.find().first()).isEqualTo(json("_id: 1, a: 1")); }
@Test public void testFindOneAndUpdateUpsertReturnBefore() { Document result = collection.findOneAndUpdate(json("_id: 1"), json("$inc: {a: 1}"), new FindOneAndUpdateOptions().upsert(true).returnDocument(ReturnDocument.BEFORE)); assertThat(result).isEqualTo(json("")); assertThat(collection.find().first()).isEqualTo(json("_id: 1, a: 1")); }
/** * Finds the first document in the query and updates it. * * @param query * query to match * @param fields * fields to be returned * @param sort * sort to apply before picking first document * @param update * update to apply. This must contain only update operators * @param returnNew * if true, the updated document is returned, otherwise the old * document is returned (or it would be lost forever) * @param upsert * do upsert (insert if document not present) * @return the object */ public T findAndModify(Document query, Document fields, Document sort, Document update, boolean returnNew, boolean upsert) { return mongoCollection.findOneAndUpdate(serializeFields(query), update, new FindOneAndUpdateOptions().returnDocument(returnNew ? ReturnDocument.AFTER : ReturnDocument.BEFORE).projection(fields).sort(sort).upsert(upsert)); }
@Override public Number nextValue(NextValueRequest request) { String valueColumnName = request.getKey().getMetadata().getValueColumnName(); MongoCollection<Document> sequenceCollection = getCollection( request.getKey().getTable(), null ); Document sequenceId = prepareIdObject( request.getKey() ); Document setInitialValueOnInsert = new Document(); addSubQuery( "$setOnInsert", setInitialValueOnInsert, valueColumnName, request.getInitialValue() + request.getIncrement() ); // I don't trust to make this a constant because the object is not immutable FindOneAndUpdateOptions enableUpsert = new FindOneAndUpdateOptions().upsert( true ); Document originalDocument = sequenceCollection.findOneAndUpdate( sequenceId, setInitialValueOnInsert, enableUpsert ); Object nextValue = null; if ( originalDocument == null ) { return request.getInitialValue(); // first time we ask this value } else { // all columns should match to find the value Document incrementUpdate = new Document(); addSubQuery( "$inc", incrementUpdate, valueColumnName, request.getIncrement() ); Document beforeUpdateDoc = sequenceCollection.findOneAndUpdate( sequenceId, incrementUpdate, new FindOneAndUpdateOptions().upsert( true ) ); nextValue = beforeUpdateDoc.get( valueColumnName ); } return (Number) nextValue; }
@Override public Number nextValue(NextValueRequest request) { String valueColumnName = request.getKey().getMetadata().getValueColumnName(); MongoCollection<Document> sequenceCollection = getCollection( request.getKey().getTable(), null ); Document sequenceId = prepareIdObject( request.getKey() ); Document setInitialValueOnInsert = new Document(); addSubQuery( "$setOnInsert", setInitialValueOnInsert, valueColumnName, request.getInitialValue() + request.getIncrement() ); // I don't trust to make this a constant because the object is not immutable FindOneAndUpdateOptions enableUpsert = new FindOneAndUpdateOptions().upsert( true ); Document originalDocument = sequenceCollection.findOneAndUpdate( sequenceId, setInitialValueOnInsert, enableUpsert ); Object nextValue = null; if ( originalDocument == null ) { return request.getInitialValue(); // first time we ask this value } else { // all columns should match to find the value Document incrementUpdate = new Document(); addSubQuery( "$inc", incrementUpdate, valueColumnName, request.getIncrement() ); Document beforeUpdateDoc = sequenceCollection.findOneAndUpdate( sequenceId, incrementUpdate, new FindOneAndUpdateOptions().upsert( true ) ); nextValue = beforeUpdateDoc.get( valueColumnName ); } return (Number) nextValue; }
@Override public Optional<SimpleLock> lock(LockConfiguration lockConfiguration) { Date now = now(); Bson update = combine( set(LOCK_UNTIL, Date.from(lockConfiguration.getLockAtMostUntil())), set(LOCKED_AT, now), set(LOCKED_BY, hostname) ); try { // There are three possible situations: // 1. The lock document does not exist yet - it is inserted - we have the lock // 2. The lock document exists and lockUtil <= now - it is updated - we have the lock // 3. The lock document exists and lockUtil > now - Duplicate key exception is thrown getCollection().findOneAndUpdate( and(eq(ID, lockConfiguration.getName()), lte(LOCK_UNTIL, now)), update, new FindOneAndUpdateOptions().upsert(true) ); return Optional.of(new MongoLock(lockConfiguration)); } catch (MongoServerException e) { if (e.getCode() == 11000) { // duplicate key //Upsert attempts to insert when there were no filter matches. //This means there was a lock with matching ID with lockUntil > now. return Optional.empty(); } else { throw e; } } }
public Document findAndUpdate(Bson query, Bson projection, Bson sort, Bson update, QueryOptions options) { boolean upsert = false; boolean returnNew = false; if (options != null) { if (projection == null) { projection = getProjection(projection, options); } upsert = options.getBoolean("upsert", false); returnNew = options.getBoolean("returnNew", false); } FindOneAndUpdateOptions findOneAndUpdateOptions = new FindOneAndUpdateOptions() .sort(sort) .projection(projection) .upsert(upsert) .returnDocument(returnNew ? ReturnDocument.AFTER : ReturnDocument.BEFORE); return dbCollection.findOneAndUpdate(query, update, findOneAndUpdateOptions); }
/** * Finds the first document in the query and updates it. * * @param query * query to match * @param fields * fields to be returned * @param sort * sort to apply before picking first document * @param update * update to apply * @param returnNew * if true, the updated document is returned, otherwise the old * document is returned (or it would be lost forever) * @param upsert * do upsert (insert if document not present) * @return the object */ public T findAndModify(DBQuery.Query query, Document fields, Document sort, DBUpdate.Builder update, boolean returnNew, boolean upsert) { return mongoCollection.findOneAndUpdate(serializeQuery(query), update.serializeAndGetAsDocument(objectMapper, type), new FindOneAndUpdateOptions().returnDocument( returnNew ? ReturnDocument.AFTER : ReturnDocument.BEFORE).projection(fields).sort(sort).upsert(upsert)); }
.sort( sort ) .bypassDocumentValidation( ( bypass != null ? bypass : false ) ) .upsert( ( upsert != null ? upsert : false ) ) .projection( fields ) .returnDocument( ( returnNewDocument != null ? returnNewDocument : false ) ? ReturnDocument.AFTER : ReturnDocument.BEFORE )