问题
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);
I get following error, what is wrong:
java.lang.RuntimeException: java.lang.IllegalArgumentException: Document field names can't start with '$' (Bad Key: '$set')
u.toString output is :
{ "orgId" : 2 , "$set" : { "accounts.001" : "EXAMPLE"}}
回答1:
You should not have the { "orgId" : 2 }
in the update document.
Remove this line from the code and it should work fine.
u.append("orgId", orgId);
The reason you triggered the error was that there are two ways to specify the update for a document and you created a cross bread of both. The options are:
- Provide the complete document for the update. For this model the existing document is overwritten by the provided document.
- Uses update operators to modify the existing document in the collection.
If you use the second version then all of the "top level keys" in the update document will start with a $
. If you use the first option then none of the top level keys will start with a $
. The code looked at the first field, thought it was a replacement document and then failed when it tried to validate the rest of the document was valid since keys in documents cannot start with a $
(lest the be confused with update or query documents).
Edit:
In the case of an upsert (e.g., the document does not already exist and you flag the update to allow the upsert) query's exact match operators are used to seed the document. For the above example we get a seed document of { "orgId" : 2 }
. The server will then apply the update operators and save the result.
来源:https://stackoverflow.com/questions/25131269/document-field-names-cant-start-with-bad-key-set