This exception:
Exception in thread \"Thread-1\" java.lang.IllegalArgumentException: Invalid BSON field name id
at org.bson.AbstractBsonWriter.writeName(
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.
createAt and updateAt with current datetime.name and updateAt 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 here
Document 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 match
upsert.append("$setOnInsert", toInsert)
.append("$set", toUpdate);
UpdateResult result = collection.updateOne(query, toUpdate,
new UpdateOptions().upsert(true));