Version 9

    Mapping to MongoDB

     

    This page aims at collecting thoughs on how to map to MongoDB. While it essentially focus on queries, we can imagine sections pertaining to

    data mapping or option mapping etc. It also should list the set of use cases that MongoDB covers well but where Hibernate OGM is not good at.

     

    Mapping JP-QL queries

    Here are a list of queries, how can these be mapped in MongoDB query language? Note that this list excludes cross document joins - at least initially.

     

    Cat is an entity

    Owner is an embedded object

    Address is an embedded object

     

    jpql: select o from java.lang.Object o //return all mapped objects from the database

    mongodb: not possible to do a single query across collections.  discuss further regarding use of polymorphic collections

     

    jpql: select c from Cat c //return all Cats

    mongodb: db.cats.find()

     

    jpql: select c.name from Cat c //return all Cat names

    mongodb: db.cats.find({}, {'name' : 1)})

     

    jpql: select c from Cat c where c.name = :name //return cats of a given name

    mongodb: db.cats.find({'name' : name})

     

    jpql: select c from Cat c where c.owner.address.city = :city //return all cats whose owner lives in a given city

    mongodb: db.cats.find({'owner.address.city' : city})

     

    jpql: select count(c) from Cat c where c.weight > :weight // return the number of cats whose weight is greater than weight

    mongodb: db.cats.find({'weight' : {$gt : weight}}).count()

     

    jpql: select cat, count( elements(cat.kittens) ) from eg.Cat cat group by cat // return each cat and for each cat the number of kittens

    mongodb: db.cats.find(...)

     

    jpql: select distinct cat.name from Cat cat // return the list of distinct cat names

    mongodb: db.cats.distinct('name')

     

    jpql: select distinct cat.name from Cat cat // return the list of distinct cat names where weight is greater than weight

    mongodb: db.cats.distinct('name', {'weight' : {$gt : weight})

     

    jpql: select cat from eg.Cat cat where cat.mate.name is not null // find all cats available for shagging

    mongodb: db.cats.find({'mate.name' : {$exists : true}})

     

    jpql: select cat from eg.Cat cat where cat.name between 'Alfonse' and 'Gertrude' // get all cats whose name is alphabetically between Alfonse and Gertrude

    mongodb: db.cats.find({'name' : {$lte : 'Alfonse', $gte : 'Gertrude'}})

     

    jpql: from eg.DomesticCat cat where cat.name not in ( 'foo', 'bar', 'baz' ) //get all cats not named after computer jokes

    mongodb: db.cats.find({'name' : {$nin : ['foo', 'bar', 'baz']}})   // question: do Cat queries find DomesticCat as well?  We need to talk about how we might handle polymorphic collections

     

    jpql: from eg.DomesticCat cat where cat.name in ( 'foo', 'bar', 'baz' ) //get all cats named after a computer joke

    mongodb: db.cats.find({'name' : {$in : ['foo', 'bar', 'baz']}})  

     

    jpql: from Order o where minelement(order.items) > 100 //get all orders containing more than 100 items

    mongodb: db.cats.find(...)

     

    jpql: from eg.DomesticCat cat order by cat.name asc, cat.weight desc, cat.birthdate // get cats ordered by name and decreasing weight and birthdate

    mongodb: db.cats.find().sort({'name' : 1, 'weight' : -1, birthdate : -1})   // should there be a 'desc' after cat.birthdate, based on the comment?

     

    jpql: select cat.color, sum(cat.weight), count(cat) from eg.Cat cat group by cat.color // get the total weight and number of cats per color

    mongodb: db.cats.aggregate( { $group: { _id: { color: 1 }, weight: { $sum: $weight },  count: { $sum: 1} } )   // note that the aggegate command requires MongoDB version >= 2.2

     

     

    Use cases not well covered by Hibernate OGM

     

    The ability to update data without having to read it is used in MongoDB to cover use cases that might not work properly in JPA.

     

    One use case is counter increments for monitoring. The counter is +1'd by several servers and MongoDB minimizes contention by

    processing these push only operations

     

    Another use case described by Jeff is the ability to add elements to a collection (with set or bag semantic, any other like map or list?) without

    having to read the whole collection. Hibernate sort of has such capability with what is called extra-lazy collections. We need to investigate if

    Emmanuel's intuition is good and that this can effectively be mapped.  See http://www.mongodb.org/display/DOCS/Updating/#Updating-ModifierOperations

    for a full list of Mongodb update operations.