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"}}
答案 0 :(得分:3)
您不应该在更新文档中包含{ "orgId" : 2 }
。
从代码中删除此行,它应该可以正常工作。
u.append("orgId", orgId);
您触发错误的原因是有两种方法可以指定文档的更新,并且您创建了两者的交叉面包。选项包括:
如果您使用第二个版本,则更新文档中的所有“顶级密钥”将以$
开头。如果您使用第一个选项,则所有顶级键都不会以$
开头。代码查看了第一个字段,认为它是替换文档,然后在尝试验证文档的其余部分是否有效时失败,因为文档中的密钥无法以$
开头(以免与更新或查询文件)。
编辑:
在upsert的情况下(例如,文档尚不存在并且您标记更新以允许upsert)查询的完全匹配运算符用于为文档设定种子。对于上面的示例,我们获得了{ "orgId" : 2 }
的种子文档。然后,服务器将应用更新运算符并保存结果。