MongoDb upsert exception invalid BSON field
updateOne
for updating document fields using update operators. You need replaceOne
which takes the replacement document.
_collection.replaceOne( trackID, track, new UpdateOptions().upsert( true ));
More here
Update Operators: https://docs.mongodb.com/manual/reference/operator/update-field/
Update One:https://docs.mongodb.com/manual/reference/method/db.collection.updateOne/
Replace One: https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/
Another option is setOnInsert
, as shown in the document of MongoDB:
https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/
The operation works only when upsert
is true
.
In your case, you should put fields not to be modified in a document, and fields to be updated in another document, and in the third document, prepend $setOnInsert
and $set
as key, respectively.
A big advantage of $setOnInsert
is that when inserting, it will perform $setOnInsert
and $set
part, but when updating, only $set
will be executed.
For example, we have a document to insert/update, which has 5 fields: name
, age
, gender
, createAt
, updateAt
.
- When I do a query by field "name" and find no match, I want to insert the document with 5 fields, and fill
createAt
andupdateAt
with current datetime. - When I do a query by "name" and find a match, I want to update
name
andupdateAt
with current datetime.
What I do is:
query = Filters.eq("name", nameToSearch);Document upsert = new Document();Date now = new Date();//only fields not mentioned in "$set" is needed hereDocument toInsert = new Document() .append("age", newAge) .append("gender", genderString) .append("createAt", now);//the fields to update here, whether on insert or on update.Document toUpdate = new Document().append("name", nameToSearch) .append("updateAt", now);//will: // - insert 5 fields if query returns no match// - updates 2 fields if query returns matchupsert.append("$setOnInsert", toInsert) .append("$set", toUpdate);UpdateResult result = collection.updateOne(query, toUpdate, new UpdateOptions().upsert(true));