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
c1andc2different? - How can I instantiate collections that behave like
c1when 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?