|
Datastore
A type-safe set of operations for mongodb
Featured DatastoreThe 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 MethodsGet 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 MethodsThe 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 MethodsThis 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 MethodsThis 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));FindAndDeleteOne 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 MethodsUpdates 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 CapsThese 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(...)) | |
How do I find and delete multiple objects?
See the Delete section and note how a query is passed in. ds.delete( ds.createQuery(Hotel.class).filter("pendingDelete", true) );
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?
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.
The error is something like: can't do non-multi update with query that doesn't have the shard key
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?
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.
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>
Datastore ds = ...
how do we initialize? You have never mentioned it and for a novice like, it becomes a headache.