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"}}
更新文档中不应该有{ "orgId" : 2 }
。
从代码中删除这一行,它应该可以正常工作。
u.append("orgId", orgId);
触发错误的原因是有两种方法可以指定文档的更新,并且您创建了这两种方法的交叉面包。选项为:
- 提供完整的更新文档。对于这个模型,现有的文档被提供的文档覆盖。
- 使用更新操作符修改集合中的现有文档。
如果您使用第二个版本,那么更新文档中的所有"顶级键"都将以$
开头。如果您使用第一个选项,那么没有一个顶级键将以$
开头。代码查看了第一个字段,认为它是一个替换文档,然后当它试图验证文档的其余部分是否有效时失败,因为文档中的键不能以$
开头(以免与更新或查询文档混淆)。
在upsert的情况下(例如,文档不存在,并且您标记更新以允许upsert),查询的精确匹配操作符用于为文档播种。对于上面的例子,我们得到{ "orgId" : 2 }
的种子文档。然后服务器将应用更新操作符并保存结果。