0.1 is a deprecated version, please go to main page to get up-to-date documentation

By default, Jongo uses Jackson to (un)marshall objects: a no-arg constructor, even private, is enough to write an object into Mongo and read from it.

Note that every Mongo document have an _id field. Defining this field Java side can be done two ways: the object field can be named _id or annotated with @JsonProperty("_id"). The object type can be ObjectId – it will be generated Mongo side – or any Java type, other than array, so long as it is unique.

Careful, saving a document without _id will generate an ObjectId typed field, even if the Java object define another type for it. So, not choosing ObjectId for _id field involves always to set it before persisting.

public class Friend {
    private ObjectId _id;
public class Friend {
    private ObjectId key;
public class Friend {
    // you must generate it!
    private String _id; 

As expected with Jackson, fields are automaticaly mapped to their equivalent json properties (and complex types mapped as sub-properties). No extra annotations needed. For fine grained control over (un)marshalling, refer to Jackson documentation or use your own (un)marshaller.

Handling polymorphism

To handle polymorphism of Java objects, a field containing the class name must be set into the Mongo document. One can persist a Fox (sub-class of Animal) and manipulate it as an Animal. This feature is provided out-of-the-box by Jackson. Using another (un)marshaller implies extra work.

@JsonTypeInfo(use = Id.CLASS, include = As.PROPERTY, property = "_class")
public class Animal {
    String gender;
public class Fox extends Animal {
    boolean wild;

Using a singular reserved name, like _class, for this field is a good idea.

Find and FindOne

Query syntax is almost the same as in Mongo shell: copy/paste, it just works.
Strings have to be escaped with single quotes "{name: 'John'}", numbers don't "{age: 18}".

Iterable<Friend> all = friends.find("{name: 'John'}").as(Friend.class);
Friend john = friends.findOne("{name: 'John'}").as(Friend.class);
Friend john = friends.findOne(new ObjectId("4c...e")).as(Friend.class);

Field names only need quotes when using dot notation "{'address.city': 'London'}".

Query with parameters

Queries can be templated: add anchors # as follow friends.find("{name: #, age: #}", "John", 18)
Binded parameters can be BSON Primitives or any complex type made of those.

friends.find("{name: #, age: #}", "John", 18); //- will produce {name: 'John', age: 18}
List<String> ages = Lists.newArrayList(22, 63);
friends.find("{age: {$in:#}}", ages); //- will produce {age: {$in:[22,63]}}

Query options

Field selection

Field selection aka. partial loading is not written as in Mongo shell: Jongo exposes a fields(...) method. A json selector must be provided: {field: 1} to include it, {field: 0} to exclude it.

friends.find("{}").fields("{lastname: 1, address: 1}").as(User.class);


Documents can be sorted in ascending or descending order using a json selector: {field: 1} for ascending, {field: -1} for descending.

friends.find("{}").sort("{firstname: 1}").as(User.class);
friends.find("{}").sort("{lasttname: -1}").as(User.class);

Skip and Limit

Behaviour similar to Java driver DBCursor.



Behaviour similar to Java driver DBCollection.distinct(...).

friends.distinct("address", "", Address.class);
friends.distinct("address", "{name: 'John'}", Address.class);


Behaviour similar to Java driver DBCollection.count(...).

friends.count("{name: 'John'}");

Advanced query

Geospacial indexing

Using Mongo geospacial capacities requires an index and some BSON operators.

friends.ensureIndex("{address: '2d'}");
friends.find("{address: {$near: [0, 0], $maxDistance: 5}}").as(Address.class);

Complete query syntax

Mongo uses a behind the scenes syntactic sugar for methods like sort(...), limit(...) and others. The complete expression can also be used in Jongo.

friends.find("{$query: {}, $maxScan: 2}").as(Friend.class);
friends.find("{$query: {}, $orderby: {name: 1}}").as(Friend.class);


Simply pass an object to the save(...) method, built-in Jackson marshaller will be used to convert it to json. Object mapping section defines what objects have to look like.

friends.save(new Friend("Joe", 27));


In early version of Jongo 'upsert' is not available and update is always in 'multi' mode.

friends.update("{name: 'Joe'}", "{$inc: {age: 1}}");


Remove works as if you were in Mongo shell.

friends.remove("{name: 'Joe'}");

Jongo is lighting fast. Not because it is made of ancient wood and magic stones, but because it binds Jackson — the fastest Java json (un)marshalling library — to Mongo Java driver with the slightest glue code possible.

Jongo's performance is currently under our microscope and we already noticed some great improvements over our main competitor: Morphia. Keep tuned.

Using a custom result mapper

If one prefers to manually map objects (ie. without a (un)marshaller), he can implements ResultMapper. Each result entity will be passed to the inherited map(String json) method.

Iterable<Integer> ages = col.find("{'name':'John'}").map(
    new ResultMapper<Integer>() {
        public String map(String json) {
            DBObject result = (DBObject) JSON.parse(json);
            return result.get("age");

Using a custom (un)marshaller

Instead of Jackson, one can provide his own implementation of Marshaller and Unmarshaller.

Marshaller marshaller = new Marshaller() {
    <T> String marshall(T obj) { ... }
Unmarshaller unmarshaller = new Unmarshaller() {
    <T> T unmarshall(String json, Class<T> clazz) { ... }
Jongo jongo = new Jongo(mongo.getDB("dbname"), marshaller, unmarshaller);

Jongo is deployed into OSS Sonatype (Maven repository hosting service for open source projects).

Add dependency into your pom.xml