文档字段名称不能以' $'开头。 (坏键:' $ set')

时间:2014-08-05 04:35:18

标签: mongodb mongodb-java

    BasicDBObject u = new BasicDBObject();
    DBObject q = new BasicDBObject();
    q.put("orgId", orgId);
    u.append("orgId", orgId);

    if(accounts.keySet().size() > 0) {
        BasicDBObject setObj = new BasicDBObject();
        for (String key : accounts.keySet()) {
            String fieldToUpdate = "accounts." + key;
            setObj.append(fieldToUpdate, accounts.get(key));
        }
        u.append("$set", setObj);
    } 

    DBCollection collection = db.getCollection(collectionName);
    WriteResult result = collection.update(q, u, true, false);

我得到以下错误,出了什么问题:

java.lang.RuntimeException: java.lang.IllegalArgumentException: Document field names can't start with '$' (Bad Key: '$set')

u.toString输出为:

{ "orgId" : 2 , "$set" : { "accounts.001" : "EXAMPLE"}}

1 个答案:

答案 0 :(得分:3)

您不应该在更新文档中包含{ "orgId" : 2 }

从代码中删除此行,它应该可以正常工作。

u.append("orgId", orgId);

您触发错误的原因是有两种方法可以指定文档的更新,并且您创建了两者的交叉面包。选项包括:

  1. 提供更新的完整文档。对于此模型,现有文档将被提供的文档覆盖。
  2. 使用更新运算符修改集合中的现有文档。
  3. 如果您使用第二个版本,则更新文档中的所有“顶级密钥”将以$开头。如果您使用第一个选项,则所有顶级键都不会以$开头。代码查看了第一个字段,认为它是替换文档,然后在尝试验证文档的其余部分是否有效时失败,因为文档中的密钥无法以$开头(以免与更新或查询文件)。

    编辑:

    在upsert的情况下(例如,文档尚不存在并且您标记更新以允许upsert)查询的完全匹配运算符用于为文档设定种子。对于上面的示例,我们获得了{ "orgId" : 2 }的种子文档。然后,服务器将应用更新运算符并保​​存结果。