remove nested mongo document using Casbah

126 views Asked by At

Given the following data structure:

{
  "_id" : ObjectId("55760212e4b011ee8c72fb1f"),
  "firstname" : "joe",
  "lastname" : "blow",
  "email" : "[email protected]",
  "sysadmin" : false,
  "siteadmin" : false,
  "sites" : [ 
    {
      "siteId" : ObjectId("55760212e4b011ee8c72fb1e"),
      "notification" : false
    }
  ]
}

I'm trying to $pull a nested sites object using an ObjectId as search criteria. The following code:

val siteSearch = MongoDBObject("siteId" -> siteId)
val query = MongoDBObject("sites" -> siteSearch)
db(collection).update(query, $pull(query))

generates for following query

{ "sites" : { "siteId" : { "$oid" : "55760212e4b011ee8c72fb1e"}}}

It's not removing the site, I'm assuming because I want the query to look like:

{ "sites" : { "siteId" : ObjectId("55760212e4b011ee8c72fb1e")}}

I'm not sure how to make Cashbah issue the correct query.

1

There are 1 answers

3
Sylvain Leroux On BEST ANSWER

First, { "$oid" : "55760212e4b011ee8c72fb1e"} is the JSON representation of the BSON 12 bytes ObjectId type. Basically, the same thing as ObjectId("55760212e4b011ee8c72fb1e"). See http://docs.mongodb.org/manual/reference/mongodb-extended-json/#oid

Then, as you match against an array item, you need to use $elemMatch in your query. But, as $pull applies its query to each element as though it were a top-level object, you don't need it in the update expression.

val siteSearch = MongoDBObject("siteId" -> siteId)
val elemMatch = MongoDBObject("$elemMatch" -> siteSearch)

val query = MongoDBObject("sites" -> elemMatch)
val target = MongoDBOjbect("sites" -> siteSearch)

db(collection).update(query, $pull(target))

I don't have Casbah at hand right no, but using the Casbah DSL, you might use that alternate syntax I think:

val query = "sites" $elemMatch siteSearch

From a Mongo shell perspective, this should be the same as:

query = {
    "sites" : {
        "$elemMatch" : {
            "siteId" : ObjectId("55760212e4b011ee8c72fb1e")
        }
    }
}

target = {
    "sites" : {
            "siteId" : ObjectId("55760212e4b011ee8c72fb1e")
    }
}
db.test.update(query, {$pull: target})