I’m currently using Casbah with MongoDB for implementing web service. I am having no problems with it so far. I am using Scala as well.
However, I was just curious to know if there is something better than Casbah for doing a lot of find/findOne type queries.
I came across Rogue, a type-safe Scala based DSL that says would make querying easier and more readable.
So, I wanted to know if it would be useful to shift to Rogue, so that as the web service project gets bigger and more complex, it might help to have Rogue’s support for querying?
Just wanted to find out if I should continue or shift to something better.
At the moment, Rogue only works against Lift’s MongoDB-Record system.
Part of the reason it offers full type safety is that it uses a strong, well defined object structure for Lift-Record. You have a lot less ability to do ‘free form’ queries as you have a full structure in place for it. Here’s what I mean by way of a demo of Lift-Record + Rogue I did for a recent Scala Webinar. Some stuff has changed in Lift & Rogue since I did this so code might be slightly out of date but is still representative. This is the Lift-Record model for MongoDB:
As you can see, you are required to define your MongoDB Data model ahead of time in order to gain the benefit of strongly typed, safe queries… Rogue enforces most of it at compile time. Here are some Rogue examples against this model:
Notice I am not saying Rogue and Lift-Record aren’t awesome, just that they work off of a strongly defined compile time data model.
If instead you’d like to use a similar context with Casbah, we do have a builtin DSL which is designed to mimic MongoDB’s inbuilt Query model as closely as possible. It works against any arbitrary underlying model, but does a LOT to enforce levels of type safety where possible. Here is a (slightly dated as its from the same presentation) example of Casbah’s Querying:
Notably we are querying against a free form model but using DSL operators instead of nested MongoDB definitions. There are lots of fantastic mappings of operators, right down to the $type operator to test a type using class manifests for compiletime safety:
(Note: You need to either import the casbah-query package and its related imports to your code or use the default ‘casbah’ import from pre-modulisation). The Specs for Casbah currently have full coverage for every DSL operator; the docs lag behind at the moment but the Specs serve as a great introduction to their usage. Note there are two kinds of operators in Casbah, just like in MongoDB.
I know this is a rather detailed answer but I wanted to make sure that you understand your options, as well as the limitations of both solutions. Casbah will give you a DSL that maps closely to MongoDB and removes some of the syntactic cruft (Keep in mind also Casbah provides a
getAs[T]method onDBObjectto ask for a value from theDBObjectas a specific type, which people often overlook); many users are unaware the DSL exists before they go seeking something to do what is built in. However, Casbah’s Query DSL also looks a bit “crufty” in some peoples opinions… as the author of it I prefer it’s simplicity and elegance as I need only remember the **MONGODB* syntax for querying, and not both MongoDB and another DSL. It is also based on free form querying and doesn’t provide the same structured, compile time type safe & aware facilities that Rogue does.By contrast though, Rogue also requires a fully defined Record model against it, which doesn’t fit into every application.
I’d love to hear however where things can be improved on either product if there’s a “middle ground” for your needs which either product doesn’t properly meet.