Search code examples
mongodbscalacasbah

MongoDB cross-collection query with casbah


I have two collections like follwoing,

customers:
  {id: 1, name: "foo"}
  {id: 2, name: "bar"}
  {id: 3, name: "baz"}

flags:
  {cid: 1}
  {cid: 3}

Then retrieving customers whose flag is on

db.customers.find({id: {$in: db.flags.distinct("cid", {})}})

On shell this works, but I can't do the same using casbah, since casbah does not seem to support querying with function call or local variable.


Solution

  • Of course you can do this in casbah - remember db.flags.distinct returns an iterable that should be converted implicitly to a list for use in $in. Heres a test example for you:

    import com.mongodb.casbah.Imports._
    val db = MongoClient()("casbahTest")
    val customers = db("customers")
    val flags = db("flags")
    
    customers.drop()
    flags.drop()
    
    // Add some customers
    customers += MongoDBObject("_id" -> 1, "name" -> "foo")
    customers += MongoDBObject("_id" -> 2, "name" -> "bar")
    customers += MongoDBObject("_id" -> 3, "name" -> "baz")
    
    // Add some flags
    flags += MongoDBObject("cid" -> 1)
    flags += MongoDBObject("cid" -> 3)
    
    
    // Query
    // In JS: db.customers.find({id: {$in: db.flags.distinct("cid", {})}})
    
    // Long hand:
    customers.find(MongoDBObject("_id" -> MongoDBObject("$in" -> flags.distinct("cid"))))
    
    // Using Casbahs query dsl to build the MongoDBObject:
    customers.find("_id" $in flags.distinct("cid"))