MongoDB Datastores

DataNucleus supports persisting/retrieving objects to/from MongoDB datastore (using the datanucleus-mongodb plugin). If you wish to help out development of this plugin either by contributing or by sponsoring particular functionality please contact us via the DataNucleus Forum.

Datastore Connection

The following persistence properties will connect to an MongoDB instance

datanucleus.ConnectionURL=mongodb:[{server}][/{dbName}] [,{server2}[,server3}]]


If you just specify the URL as mongodb then you have a local MongoDB datastore called "DataNucleus", otherwise it tries to connect to the datastore {dbName} at {server} . The multiple {server} option allows you to run against MongoDB replica sets. So you create your PersistenceManagerFactory or EntityManagerFactory with these properties. Thereafter you have the full power of the JDO or JPA APIs at your disposal, for your MongoDB datastore. If in doubt, refer to the MongoDB tutorial example for JDO.



Queries

Access Platform allows you to query the objects in the datastore using the following

  • JDOQL - language based around the objects that are persisted and using Java-type syntax
  • JPQL - language based around the objects that are persisted and using SQL-like syntax

Some components of a filter are handled in the datastore, and the remainder in-memory. Currently any expression of a field (in the same table), or a literal are handled in-datastore, as are the operators &&, ||, >, >=, <, <=, ==, and !=.

If you want a query to be runnable on a slave MongoDB instance then you should set the query extension (JDO) / hint (JPA) slave-ok as true , and when executed it can be run on a slave instance.



Access to MongoDB 'connection'

When using JDO you can do the following to get hold of the native "DB" connection object

    tx.begin();
    ...

    // Get hold of native connection
    JDOConnection jdoConn = pm.getDataStoreConnection();
    DB db = (DB)jdoConn.getNativeConnection();
    ... (do something with the connection)
    jdoConn.close(); // Hands it back to JDO
    
    tx.commit();

Sadly JPA doesn't have such a feature



Mapping : Document name, Field names

MongoDB datastore support assumes that objects of a class are persisted to a particular "document" of a MongoDB datastore. Similarly a field of a class is persisted to a particular "field" of that "document". This is the basis of MongoDB persistence. The main thing you want to do when mapping is to specify the document name, and the names of the fields in the MongoDB document. These are specified using the table and column metadata controls.



Mapping : Embedded Persistable fields

When you have a field in a class that is of a persistable type you sometimes want to store it with the owning object. In this case you can use JDO/ JPA embedding of the field. DataNucleus offers two ways of performing this embedding

  • The default is to store the object in the field as a sub-document (nested) of the owning document. Similarly if that sub-object has a field of a persistable type then that can be further nested.
  • The alternative is to store each field of the sub-object as a field of the owning document (flat embedding). Similarly if that sub-object has a field of a persistable type then it can be flat embedded in the same way

@PersistenceCapable
public class A
{
    @Embedded
    B b;

    ...
}

This example uses the default embedding, using a nested document within the owner document, and could look something like this

{ "name" : "A Name" ,
  "id" : 1 ,
  "b" : { "name" : "B name" ,
          "description" : "the description"}
}

The alternative would be

@PersistenceCapable
public class A
{
    @Embedded
    @Extension(vendorName="datanucleus", key="nested", value="false")
    B b;

    ...
}

and this will use flat embedding , looking something like this

{ "name" : "A Name" ,
  "id" : 1 ,
  "b_name" : "B name" ,
  "b_description" : "the description"
}


Mapping : Embedded Collection elements

When you have a field in a class that is of a Collection type you sometimes want to store it with the owning object. In this case you can use JDO/ JPA embedding of the field. So if we have

@PersistenceCapable
public class A
{
    @Element(embedded="true")
    Collection<b> bs;

    ...
}

and would look something like this

{ "name" : "A Name" ,
  "id" : 1 ,
  "bs" :
      [
        { "name" : "B Name 1" ,
          "description" : "desc 1"} ,
        { "name" : "B Name 2" ,
          "description" : "desc 2"} ,
        { "name" : "B Name 3" ,
          "description" : "desc 3"}
      ]
}


References

Below are some references using this support