使用Casbah删除嵌套的mongo文档

时间:2015-06-08 21:08:11

标签: mongodb scala casbah

鉴于以下数据结构:

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

我正在尝试$pull使用sites作为搜索条件的嵌套ObjectId对象。以下代码:

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

生成以下query

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

这不是删除网站,我假设因为我希望query看起来像:

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

我不确定如何让Cashbah发出正确的查询。

1 个答案:

答案 0 :(得分:1)

首先,{ "$oid" : "55760212e4b011ee8c72fb1e"}BSON 12 bytes ObjectId type的JSON表示。基本上,与ObjectId("55760212e4b011ee8c72fb1e")相同。见http://docs.mongodb.org/manual/reference/mongodb-extended-json/#oid

然后,当您与数组项匹配时,您需要在查询中使用$elemMatch但是,因为$pull将其查询应用于每个元素,就像它是顶级对象一样,在更新表达式中不需要它。

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))

我手头没有Casbah,但使用Casbah DSL,您可能会使用我认为的替代语法:

val query = "sites" $elemMatch siteSearch

从Mongo shell的角度来看,这应该与:

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

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