I'm working with Grails Mongo domain objects and I've noticed that I get very different behavior with the following two ways to access a collection:
c1
: collection name is known at compile time:
def c1 = MyDomainClass.collection
c2
: collection name is only known at runtime
def c2 = AnyDomainClass.collection.DB.getCollection(collectionName)
c1
and c2
have the same class, but behave differently!
Both c1
and c2
have the class com.mongodb.DBApiLayer$MyCollection
but they behave differently.
Specifically, c1
supports "friendly" interactions like passing Maps directly to GMongo methods, e.g.
c1.find([tag:'spicy']).sort([created:1])
Whereas c2
only works with DBObject
parameters like:
c2.find(new BasicDBObject([tag:'spicy'])).sort(new BasicDBObject([created:1]))
I prefer the syntax in #1, and I would like to be able to use that syntax with objects even when I don't know the collection at compile time. In other words, I want to be able to dynamically access collections (which I can do with #2), but using the "friendly" syntax from #1.
My questions are:
- How are
c1
andc2
different? - How can I instantiate collections that behave like
c1
when the collection is unknown at compile time? - At what layer of the Grails/GORM/GMongo stack are objects wrapped to support map-to-DBObject conversions, and how is this done?