The Java driver for MongoDB does not provide any utility classes that could help with building update queries. If you want to create a query to update or increment field values, you usually have to use BasicDBObjectBuilder. This is an intuitive approach, but queries defined in such a way are quite hard to read and maintain.
This post is written for the MongoDB Java driver version 2.4
Have a look at the MongoDB QueryBuilder , which is a utility for creating search queries:
DBCollection collection = new Mongo("localhost", 27017)
.getDB("test").getCollection("users");
DBObject criteria = new QueryBuilder().put("name")
.is("Perry").and("age").greaterThan(20).get();
DBObject doc = collection.findOne(criteria);As you can see, the criteria declaration here is very clear; it is based on the builder pattern, which is highly applicable when it comes to creating objects that have an undefined number of parameters.
Let’s build a utility for update operations that works the same as the QueryBuilder:
/**
* The utility for creating update queries.
*/
public class Builder {
/**
* The update query.
*/
private final DBObject query;
/**
* Initializes the update builder.
*/
public Builder() {
query = new BasicDBObject();
}
/**
* Sets the new value for the field.
*
* @param key field name
* @param object value to set
* @return Builder instance
*/
public Builder set(final String key,
final Object object) {
addToQuery(Operators.SET, key, object);
return this;
}
/**
* Increments the field by a specified value.
*
* @param key field name
* @param value number value
* @return Builder instance
*/
public Builder inc(final String key,
final int value) {
addToQuery(Operators.INC, key, value);
return this;
}
/**
* Deletes the field.
*
* @param key field name
* @return Builder instance
*/
public Builder unset(final String key) {
addToQuery(Operators.UNSET, key, 1);
return this;
}
/**
* Checks whether the builder is empty.
*
* @return true if the builder is empty, false otherwise
*/
public boolean isEmpty() {
return query.keySet().isEmpty();
}
/**
* Creates the DBObject-based query to be used for update operations.
*
* @return the query instance
*/
public DBObject get() {
return query;
}
/**
* Adds the operation to the query.
*
* @param operator update operator
* @param key param to update
* @param object value to set
*/
private void addToQuery(final String operator,
final String key,
final Object object) {
final BasicDBObject subQuery = query.get(operator) != null ?
(BasicDBObject) query.get(operator) : new BasicDBObject();
query.put(operator, subQuery.append(key, object));
}
}/**
* MongoDB keywords for update operations.
*/
public class Operators {
public final static String SET = "$set";
public final static String INC = "$inc";
public final static String UNSET = "$unset";
}The builder can be used in the following way:
DBCollection collection = new Mongo("localhost", 27017)
.getDB("test").getCollection("users");
DBObject criteria = new QueryBuilder().put("name")
.is("Perry").get();
DBObject update = new Builder().inc("age", 1).get();
collection.update(criteria, update);
