Java, nosql, mongodb, howto technologies

MongoDB java driver. The custom builder for update operations.

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 intuitive approach, but queries defined in such a way are quite hard to read and maintain.

Have a look at the MongoDB QueryBuilder which is a utility for creating search queries:

1
2
3
4
5
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
 * 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));
    }
}
1
2
3
4
5
6
7
8
9
10
11
/**
 * 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:

1
2
3
4
5
6
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);

This post is written for the MongoDB Java driver version 2.4

Looking to hire a software developer?
Don't hesitate to contact us.

Comments