在Casbah中执行包含$ addToSet的MongoDB findAndModify查询

时间:2013-06-09 18:03:42

标签: mongodb scala casbah

我是scala和cashbah的新手。我想

  • 如果存在(通过_id)更新文档并创建if不存在。
  • 更新时,更新一些关键值
  • 在更新时,更新某些值为集合的键,包括一些数据到这些集合。

为了达到这个目的,我写了这个:

DBObject = MongoDBObject("_id" -> uri.toString) ++
      $addToSet("appearsOn" -> sourceToAppend) ++
      $addToSet("hasElements" -> elementsToAppend) ++
      $addToSet("hasTriples" -> triplesToAppend) ++
      MongoDBObject("uDate" -> new DateTime)

    /* Find and replace here! */
    OntologyDocument.dao.collection.findAndModify(
      query = MongoDBObject({"_id" -> uri.toString}),
      update = update,
      upsert = true,
      fields = null,
      sort = null,
      remove = false,
      returnNew = true
    )

_id查看的文档,添加到appearsOn hasElements hasTriplesuDate的新项目已更新。

sourceToAppend elementsToAppendtriplesToAppendList[String]

当我运行时,我收到了这个错误:

java.lang.IllegalArgumentException: fields stored in the db can't start with '$' (Bad Key: '$addToSet')
    at com.mongodb.DBCollection.validateKey(DBCollection.java:1444) ~[mongo-java-driver-2.11.1.jar:na]

我没理解。这个查询有什么问题? $addToSet不是一个字段,为什么casbah认为它是一个字段?我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

失败的原因是因为更新查询无效(它不能在js shell中工作)。

$set对于更新文档中的值是隐含的,但您不能将其与其他更新运算符(例如$addToSet)混合使用。如果您想将$set与其他集合运算符混合,那么您可以明确:

val update = $set("uDate" -> new DateTime) ++ 
             $addToSet("appearsOn" -> sourceToAppend, 
                       "hasElements" -> elementsToAppend, 
                       "hasTriples" -> triplesToAppend)

你不能$set“_id”但是在查询中它和它的upsert一样 - 它会合并,所以不要在update语句中包含它 - 否则它会出错。

最后,如果您不需要返回的文档,@ AsyaKamsky是正确的 - 使用update也是原子。