文档字段名称不能以"$"开头(错误键:"$set")


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

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

  1. 提供完整的更新文档。对于这个模型,现有的文档被提供的文档覆盖。
  2. 使用更新操作符修改集合中的现有文档。

如果您使用第二个版本,那么更新文档中的所有"顶级键"都将以$开头。如果您使用第一个选项,那么没有一个顶级键将以$开头。代码查看了第一个字段,认为它是一个替换文档,然后当它试图验证文档的其余部分是否有效时失败,因为文档中的键不能以$开头(以免与更新或查询文档混淆)。

编辑:

在upsert的情况下(例如,文档不存在,并且您标记更新以允许upsert),查询的精确匹配操作符用于为文档播种。对于上面的例子,我们得到{ "orgId" : 2 }的种子文档。然后服务器将应用更新操作符并保存结果。

最新更新