My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for

Datastore  
A type-safe set of operations for mongodb
Featured
Updated Nov 8, 2011 by scotthernandez

Datastore

The Datastore interface provides type-safe methods for accessing and storing your java objects in MongoDB. It provides get/find/save/delete methods for working with your java objects.

Get Methods

Get methods return instance(s) of your entities by its @Id. It is really just a short-cut for using find(...) with a criteria of id values. It always returns an entity, or null if none is found.

Datastore ds = ...

Hotel hotel = ds.get(Hotel.class, hotelId);

Find Methods

The find methods are a lightweight wrapper around using a Query (as with createQuery()). As a wrapper it will return a Query, which also supports Iterable<T> and the QueryResults interface.

Datastore ds = ...

//use in a loop
for(Hotel hotel : ds.find(Hotel.class, "stars >", 3))
   print(hotel);

//get back as a list
List<Hotel> hotels = ds.find(Hotel.class, "stars >", 3).asList();

//sort the results
List<Hotel> hotels = ds.find(Hotel.class, "stars >", 3).sort("-stars").asList();

//get the first matching hotel, by querying with a limit(1)
Hotel gsHotel = ds.find(Hotel.class, "name", "Grand Sierra").get();

//same as
Hotel gsHotel = ds.find(Hotel.class, "name =", "Grand Sierra").get();

Here is the list of valid operators: ["=", "==","!=", "<>", ">", "<", ">=", "<=", "in", "nin", "all", "size", "exists"]

If no operator is used, "=" is assumed, as in the last example above. "=" is the same as "==", equal "!=" is the same as "<>", not equal

Save Methods

This is where a lot of the work goes on under the covers. The methods are very straight forward.

Datastore ds = ...

Hotel hotel = new Hotel();

ds.save(hotel);

//@Id field is filled in for you (after the save), if you didn't set it.
ObjectId id = hotel.getId();

Delete Methods

This is pretty self-explanatory. The methods will delete items based on a Query, id, or an entity.

Datastore ds = ...
ds.delete(Hotel.class, "Grand Sierra Resort");
//use a query
ds.delete(ds.createQuery(Hotel.class).filter("pendingDelete", true));

FindAndDelete

One of the underlying features in MongoDB is the ability to do some operations in an atomic fashion. This can be done by deleting an Entity, and returning the deleted item at the same time. The FindAndDelete method will find the first item, and delete it (while returning it).

Datastore ds = ...
Hotel grandSierra = ds.findAndDelete(ds.get(Hotel.class, "Grand Sierra Resort"));

Update Methods

Updates are are applied at the server and allow for complicated but very efficient (when compared to saving the whole entity again) update operations.

Say you are tracking the last login for users. Each time a user successfully enters the site you can update a timestamp, but don't necessarily want to load and resave the whole user document. You can instead update the user locally and perform an efficient update of just the last login.

@Entity
class User
{
   @Id private ObjectId id;
   private long lastLogin;
   //... other members

   private Query<User> queryToFindMe()
   {
      return datastore.createQuery(User.class).field(Mapper.ID_KEY).equal(id);
   }

   public void loggedIn()
   {
      long now = System.currentTimeMillis();
      UpdateOperations<User> ops = datastore.createUpdateOperations(User.class).set("lastLogin", now);
      ds.update(queryToFindMe(), ops);
      lastLogin = now;
   }
}
//maybe add example on managing an embedded array of login times

Read more on Updating.

Ensure Indexes and Caps

These methods should be called after you have registered you entities with Morphia. It will then synchronously, by default, create your indexes, and capped collections. One option is call them each time you start your application, or via an administrative interface, or during a deployment script. It might be best to make sure indexes can be built in the background if there is already data.

If you delay index building to later in the application life-cycle you should make sure to create the capped collections (ensureCaps) at startup, before any data is persisted.

Note: Doing this on an existing system, with existing indexes and capped collections, should take no time (and do nothing). If the collection isn't capped, or has different setting you will get an error in the logs, but nothing will be done to the existing collections.

Morphia m = ...
Datastore ds = ...

m.map(MyEntity.class);
ds.ensureIndexes(); //creates all defined with @Indexed
ds.ensureCaps(); //creates all collections for @Entity(cap=@CappedAt(...))
Comment by heaths.h...@gmail.com, Dec 1, 2011

How do I find and delete multiple objects?

Comment by project member scotthernandez, Dec 1, 2011

See the Delete section and note how a query is passed in. ds.delete( ds.createQuery(Hotel.class).filter("pendingDelete", true) );

Comment by ryan...@gmail.com, Dec 5, 2011

We have tried update multiple entities (query and update in one operation). It worked in a non-sharded env. But in a sharded env, it throws errors. I guess this would be true for delete. Is there anyway to accomplish atomic update or delete with multiple objects in a sharded env?

Comment by ryan...@gmail.com, Dec 5, 2011

Correction to the above comment: For multiple objects update, we set a limit(n) or get() which is only for one object. But the query we passed in could have many results. If we do not set limit() or get(), then it is OK in sharded env. But as soon as we set the limit or just get one, the update fails in shards.

Comment by ryan...@gmail.com, Dec 5, 2011

The error is something like: can't do non-multi update with query that doesn't have the shard key

Comment by dchate...@gmail.com, Dec 15, 2011

Is the Datastore thread-safe? More precisely, can I share a single Datastore object between multiple threads, or should each thread initialize its own Datastore instance?

Comment by project member scotthernandez, Dec 15, 2011

ryang55: this is a server error and not morphia generated dchatenay: It is thread-safe and can be shared across threads but it light-weight and can be created cheaply as well.

Comment by Sheikh2...@gmail.com, Feb 7, 2012

very interesting write-up. i do believe an individual realy obtained a spot right now there. good operate. <a href="http://www.aaronbelfour.com">Aaron Blog's</a>

Comment by tamthi...@gmail.com, Apr 12, 2012

Datastore ds = ...

how do we initialize? You have never mentioned it and for a novice like, it becomes a headache.


Sign in to add a comment
Powered by Google Project Hosting