List of usage examples for com.mongodb DBCollection findAndModify
@Nullable public DBObject findAndModify(@Nullable final DBObject query, @Nullable final DBObject fields, @Nullable final DBObject sort, final boolean remove, @Nullable final DBObject update, final boolean returnNew, final boolean upsert)
From source file:com.softinstigate.restheart.db.CollectionDAO.java
License:Open Source License
/** * Upsert the collection properties.//w w w.j av a 2 s .c o m * * @param dbName the database name of the collection * @param collName the collection name * @param content the new collection properties * @param etag the entity tag. must match to allow actual write (otherwise * http error code is returned) * @param updating true if updating existing document * @param patching true if use patch semantic (update only specified fields) * @return the HttpStatus code to set in the http response */ public static int upsertCollection(String dbName, String collName, DBObject content, ObjectId etag, boolean updating, boolean patching) { DB db = DBDAO.getDB(dbName); DBCollection coll = db.getCollection(collName); if (patching && !updating) { return HttpStatus.SC_NOT_FOUND; } if (updating) { if (etag == null) { return HttpStatus.SC_CONFLICT; } BasicDBObject idAndEtagQuery = new BasicDBObject("_id", "_properties"); idAndEtagQuery.append("_etag", etag); if (coll.count(idAndEtagQuery) < 1) { return HttpStatus.SC_PRECONDITION_FAILED; } } ObjectId timestamp = new ObjectId(); Instant now = Instant.ofEpochSecond(timestamp.getTimestamp()); if (content == null) { content = new BasicDBObject(); } content.removeField("_id"); // make sure we don't change this field if (updating) { content.removeField("_crated_on"); // don't allow to update this field content.put("_etag", timestamp); } else { content.put("_id", "_properties"); content.put("_created_on", now.toString()); content.put("_etag", timestamp); } if (patching) { coll.update(PROPS_QUERY, new BasicDBObject("$set", content), true, false); return HttpStatus.SC_OK; } else { // we use findAndModify to get the @created_on field value from the existing properties document // we need to put this field back using a second update // it is not possible in a single update even using $setOnInsert update operator // in this case we need to provide the other data using $set operator and this makes it a partial update (patch semantic) DBObject old = coll.findAndModify(PROPS_QUERY, fieldsToReturn, null, false, content, false, true); if (old != null) { Object oldTimestamp = old.get("_created_on"); if (oldTimestamp == null) { oldTimestamp = now.toString(); logger.warn("properties of collection {} had no @created_on field. set to now", coll.getFullName()); } // need to readd the @created_on field BasicDBObject createdContet = new BasicDBObject("_created_on", "" + oldTimestamp); createdContet.markAsPartialObject(); coll.update(PROPS_QUERY, new BasicDBObject("$set", createdContet), true, false); return HttpStatus.SC_OK; } else { // need to readd the @created_on field BasicDBObject createdContet = new BasicDBObject("_created_on", now.toString()); createdContet.markAsPartialObject(); coll.update(PROPS_QUERY, new BasicDBObject("$set", createdContet), true, false); initDefaultIndexes(coll); return HttpStatus.SC_CREATED; } } }
From source file:com.softinstigate.restheart.db.DBDAO.java
License:Open Source License
/** * * @param dbName// w w w . jav a 2 s . co m * @param content * @param etag * @param patching * @return */ public static int upsertDB(String dbName, DBObject content, ObjectId etag, boolean patching) { DB db = client.getDB(dbName); boolean existing = db.getCollectionNames().size() > 0; if (patching && !existing) { return HttpStatus.SC_NOT_FOUND; } DBCollection coll = db.getCollection("_properties"); // check the etag if (db.collectionExists("_properties")) { if (etag == null) { return HttpStatus.SC_CONFLICT; } BasicDBObject idAndEtagQuery = new BasicDBObject("_id", "_properties"); idAndEtagQuery.append("_etag", etag); if (coll.count(idAndEtagQuery) < 1) { return HttpStatus.SC_PRECONDITION_FAILED; } } // apply new values ObjectId timestamp = new ObjectId(); Instant now = Instant.ofEpochSecond(timestamp.getTimestamp()); if (content == null) { content = new BasicDBObject(); } content.put("_etag", timestamp); content.removeField("_created_on"); // make sure we don't change this field content.removeField("_id"); // make sure we don't change this field if (patching) { coll.update(METADATA_QUERY, new BasicDBObject("$set", content), true, false); return HttpStatus.SC_OK; } else { // we use findAndModify to get the @created_on field value from the existing document // we need to put this field back using a second update // it is not possible in a single update even using $setOnInsert update operator // in this case we need to provide the other data using $set operator and this makes it a partial update (patch semantic) DBObject old = coll.findAndModify(METADATA_QUERY, fieldsToReturn, null, false, content, false, true); if (old != null) { Object oldTimestamp = old.get("_created_on"); if (oldTimestamp == null) { oldTimestamp = now.toString(); logger.warn("properties of collection {} had no @created_on field. set to now", coll.getFullName()); } // need to readd the @created_on field BasicDBObject createdContet = new BasicDBObject("_created_on", "" + oldTimestamp); createdContet.markAsPartialObject(); coll.update(METADATA_QUERY, new BasicDBObject("$set", createdContet), true, false); return HttpStatus.SC_OK; } else { // need to readd the @created_on field BasicDBObject createdContet = new BasicDBObject("_created_on", now.toString()); createdContet.markAsPartialObject(); coll.update(METADATA_QUERY, new BasicDBObject("$set", createdContet), true, false); return HttpStatus.SC_CREATED; } } }
From source file:com.softinstigate.restheart.db.DocumentDAO.java
License:Open Source License
/** * * * @param dbName/*w w w .java 2 s . c om*/ * @param collName * @param documentId * @param content * @param requestEtag * @param patching * @return the HttpStatus code to retrun */ public static int upsertDocument(String dbName, String collName, String documentId, DBObject content, ObjectId requestEtag, boolean patching) { DB db = DBDAO.getDB(dbName); DBCollection coll = db.getCollection(collName); ObjectId timestamp = new ObjectId(); Instant now = Instant.ofEpochSecond(timestamp.getTimestamp()); if (content == null) { content = new BasicDBObject(); } content.put("_etag", timestamp); BasicDBObject idQuery = new BasicDBObject("_id", getId(documentId)); if (patching) { content.removeField("_created_on"); // make sure we don't change this field DBObject oldDocument = coll.findAndModify(idQuery, null, null, false, new BasicDBObject("$set", content), false, false); if (oldDocument == null) { return HttpStatus.SC_NOT_FOUND; } else { // check the old etag (in case restore the old document version) return optimisticCheckEtag(coll, oldDocument, requestEtag, HttpStatus.SC_OK); } } else { content.put("_created_on", now.toString()); // let's assume this is an insert. in case we'll set it back with a second update // we use findAndModify to get the @created_on field value from the existing document // in case this is an update well need to put it back using a second update // it is not possible to do it with a single update // (even using $setOnInsert update because we'll need to use the $set operator for other data and this would make it a partial update (patch semantic) DBObject oldDocument = coll.findAndModify(idQuery, null, null, false, content, false, true); if (oldDocument != null) { // upsert Object oldTimestamp = oldDocument.get("_created_on"); if (oldTimestamp == null) { oldTimestamp = now.toString(); logger.warn("properties of document /{}/{}/{} had no @created_on field. set to now", dbName, collName, documentId); } // need to readd the @created_on field BasicDBObject created = new BasicDBObject("_created_on", "" + oldTimestamp); created.markAsPartialObject(); coll.update(idQuery, new BasicDBObject("$set", created), true, false); // check the old etag (in case restore the old document version) return optimisticCheckEtag(coll, oldDocument, requestEtag, HttpStatus.SC_OK); } else { // insert return HttpStatus.SC_CREATED; } } }
From source file:com.softinstigate.restheart.db.DocumentDAO.java
License:Open Source License
/** * * * @param exchange/*from ww w.j a v a 2 s . com*/ * @param dbName * @param collName * @param content * @param requestEtag * @return the HttpStatus code to retrun */ public static int upsertDocumentPost(HttpServerExchange exchange, String dbName, String collName, DBObject content, ObjectId requestEtag) { DB db = DBDAO.getDB(dbName); DBCollection coll = db.getCollection(collName); ObjectId timestamp = new ObjectId(); Instant now = Instant.ofEpochSecond(timestamp.getTimestamp()); if (content == null) { content = new BasicDBObject(); } content.put("_etag", timestamp); content.put("_created_on", now.toString()); // make sure we don't change this field Object _id = content.get("_id"); content.removeField("_id"); if (_id == null) { ObjectId id = new ObjectId(); content.put("_id", id); coll.insert(content); exchange.getResponseHeaders().add(HttpString.tryFromString("Location"), getReferenceLink(exchange.getRequestURL(), id.toString()).toString()); return HttpStatus.SC_CREATED; } BasicDBObject idQuery = new BasicDBObject("_id", getId("" + _id)); // we use findAndModify to get the @created_on field value from the existing document // we need to put this field back using a second update // it is not possible in a single update even using $setOnInsert update operator // in this case we need to provide the other data using $set operator and this makes it a partial update (patch semantic) DBObject oldDocument = coll.findAndModify(idQuery, null, null, false, content, false, true); if (oldDocument != null) { // upsert Object oldTimestamp = oldDocument.get("_created_on"); if (oldTimestamp == null) { oldTimestamp = now.toString(); logger.warn("properties of document /{}/{}/{} had no @created_on field. set to now", dbName, collName, _id.toString()); } // need to readd the @created_on field BasicDBObject createdContet = new BasicDBObject("_created_on", "" + oldTimestamp); createdContet.markAsPartialObject(); coll.update(idQuery, new BasicDBObject("$set", createdContet), true, false); // check the old etag (in case restore the old document version) return optimisticCheckEtag(coll, oldDocument, requestEtag, HttpStatus.SC_OK); } else { // insert return HttpStatus.SC_CREATED; } }
From source file:com.softinstigate.restheart.db.DocumentDAO.java
License:Open Source License
/** * * @param dbName// ww w . ja va2 s.co m * @param collName * @param documentId * @param requestEtag * @return */ public static int deleteDocument(String dbName, String collName, String documentId, ObjectId requestEtag) { DB db = DBDAO.getDB(dbName); DBCollection coll = db.getCollection(collName); BasicDBObject idQuery = new BasicDBObject("_id", getId(documentId)); DBObject oldDocument = coll.findAndModify(idQuery, null, null, true, null, false, false); if (oldDocument == null) { return HttpStatus.SC_NOT_FOUND; } else { // check the old etag (in case restore the old document version) return optimisticCheckEtag(coll, oldDocument, requestEtag, HttpStatus.SC_NO_CONTENT); } }
From source file:com.streamreduce.storm.MongoClient.java
License:Apache License
/** * Updates the collection that tracks the last processed event date of the spouts. * * @param spoutName name of the spout * @param lastProcessedEventDate last processed event date */// w w w . jav a 2s .c o m public void updateLastProcessedEventDate(String spoutName, long lastProcessedEventDate) { DB connectionsDb = getDB("nodeablemsgdb"); DBCollection eventCollection = connectionsDb.getCollection("spoutLastProcessedDate"); BasicDBObject query = new BasicDBObject(); query.put("spoutName", spoutName); BasicDBObject update = new BasicDBObject(); update.put("spoutName", spoutName); update.put("lastProcessedEventDate", lastProcessedEventDate); eventCollection.findAndModify(query, null, null, false, update, false, true); }
From source file:org.apache.jackrabbit.oak.plugins.document.mongo.MongoDocumentStore.java
License:Apache License
@SuppressWarnings("unchecked") @CheckForNull// www . j ava2 s .c o m private <T extends Document> T findAndModify(Collection<T> collection, UpdateOp updateOp, boolean upsert, boolean checkConditions) { DBCollection dbCollection = getDBCollection(collection); // make sure we don't modify the original updateOp updateOp = updateOp.copy(); DBObject update = createUpdate(updateOp, false); Lock lock = null; if (collection == Collection.NODES) { lock = nodeLocks.acquire(updateOp.getId()); } final Stopwatch watch = startWatch(); boolean newEntry = false; try { // get modCount of cached document Long modCount = null; T cachedDoc = null; if (collection == Collection.NODES) { cachedDoc = (T) nodesCache.getIfPresent(updateOp.getId()); if (cachedDoc != null) { modCount = cachedDoc.getModCount(); } } // perform a conditional update with limited result // if we have a matching modCount if (modCount != null) { QueryBuilder query = createQueryForUpdate(updateOp.getId(), updateOp.getConditions()); query.and(Document.MOD_COUNT).is(modCount); WriteResult result = dbCollection.update(query.get(), update); if (result.getN() > 0) { // success, update cached document if (collection == Collection.NODES) { NodeDocument newDoc = (NodeDocument) applyChanges(collection, cachedDoc, updateOp); nodesCache.put(newDoc); } // return previously cached document return cachedDoc; } } // conditional update failed or not possible // perform operation and get complete document QueryBuilder query = createQueryForUpdate(updateOp.getId(), updateOp.getConditions()); DBObject oldNode = dbCollection.findAndModify(query.get(), null, null /*sort*/, false /*remove*/, update, false /*returnNew*/, upsert); if (oldNode == null) { newEntry = true; } if (checkConditions && oldNode == null) { return null; } T oldDoc = convertFromDBObject(collection, oldNode); if (oldDoc != null) { if (collection == Collection.NODES) { NodeDocument newDoc = (NodeDocument) applyChanges(collection, oldDoc, updateOp); nodesCache.put(newDoc); updateLocalChanges(newDoc); } oldDoc.seal(); } else if (upsert) { if (collection == Collection.NODES) { NodeDocument doc = (NodeDocument) collection.newDocument(this); UpdateUtils.applyChanges(doc, updateOp); nodesCache.putIfAbsent(doc); updateLocalChanges(doc); } } else { // updateOp without conditions and not an upsert // this means the document does not exist } return oldDoc; } catch (Exception e) { throw DocumentStoreException.convert(e); } finally { if (lock != null) { lock.unlock(); } stats.doneFindAndModify(watch.elapsed(TimeUnit.NANOSECONDS), collection, updateOp.getId(), newEntry, true, 0); } }
From source file:org.einherjer.week2.samples.FindAndModifySample.java
License:Apache License
private static int getRange(String id, int range, DBCollection collection) { DBObject doc = collection.findAndModify(new BasicDBObject("_id", id), null, null, false, new BasicDBObject("$inc", new BasicDBObject("counter", range)), true, true); return (Integer) doc.get("counter") - range + 1; }
From source file:org.hibernate.ogm.datastore.mongodb.MongoDBDialect.java
License:LGPL
@Override public Number nextValue(NextValueRequest request) { DBCollection currentCollection = getCollection(request.getKey().getTable()); DBObject query = this.prepareIdObject(request.getKey()); //all columns should match to find the value String valueColumnName = request.getKey().getMetadata().getValueColumnName(); BasicDBObject update = new BasicDBObject(); //FIXME how to set the initialValue if the document is not present? It seems the inc value is used as initial new value Integer incrementObject = Integer.valueOf(request.getIncrement()); this.addSubQuery("$inc", update, valueColumnName, incrementObject); DBObject result = currentCollection.findAndModify(query, null, null, false, update, false, true); Object idFromDB;/*from ww w . j av a2s . com*/ idFromDB = result == null ? null : result.get(valueColumnName); if (idFromDB == null) { //not inserted yet so we need to add initial value to increment to have the right next value in the DB //FIXME that means there is a small hole as when there was not value in the DB, we do add initial value in a non atomic way BasicDBObject updateForInitial = new BasicDBObject(); this.addSubQuery("$inc", updateForInitial, valueColumnName, request.getInitialValue()); currentCollection.findAndModify(query, null, null, false, updateForInitial, false, true); idFromDB = request.getInitialValue(); //first time we ask this value } else { idFromDB = result.get(valueColumnName); } if (idFromDB.getClass().equals(Integer.class) || idFromDB.getClass().equals(Long.class)) { Number id = (Number) idFromDB; //idFromDB is the one used and the BD contains the next available value to use return id; } else { throw new HibernateException("Cannot increment a non numeric field"); } }
From source file:org.hibernate.ogm.dialect.mongodb.MongoDBDialect.java
License:Open Source License
@Override public void nextValue(RowKey key, IntegralDataTypeHolder value, int increment, int initialValue) { DBCollection currentCollection = this.currentDB.getCollection(key.getTable()); DBObject query = new BasicDBObject(); int size = key.getColumnNames().length; //all columns should match to find the value for (int index = 0; index < size; index++) { query.put(key.getColumnNames()[index], key.getColumnValues()[index]); }/* ww w .j av a 2s .c o m*/ BasicDBObject update = new BasicDBObject(); //FIXME should "value" be hardcoded? //FIXME how to set the initialValue if the document is not present? It seems the inc value is used as initial new value Integer incrementObject = increment == 1 ? ONE : Integer.valueOf(increment); this.addSubQuery("$inc", update, SEQUENCE_VALUE, incrementObject); DBObject result = currentCollection.findAndModify(query, null, null, false, update, false, true); Object idFromDB; idFromDB = result == null ? null : result.get(SEQUENCE_VALUE); if (idFromDB == null) { //not inserted yet so we need to add initial value to increment to have the right next value in the DB //FIXME that means there is a small hole as when there was not value in the DB, we do add initial value in a non atomic way BasicDBObject updateForInitial = new BasicDBObject(); this.addSubQuery("$inc", updateForInitial, SEQUENCE_VALUE, initialValue); currentCollection.findAndModify(query, null, null, false, updateForInitial, false, true); idFromDB = initialValue; //first time we ask this value } else { idFromDB = result.get(SEQUENCE_VALUE); } if (idFromDB.getClass().equals(Integer.class) || idFromDB.getClass().equals(Long.class)) { Number id = (Number) idFromDB; //idFromDB is the one used and the BD contains the next available value to use value.initialize(id.longValue()); } else { throw new HibernateException("Cannot increment a non numeric field"); } }