Given a document with the below structure:
{
"_id": "XXXX01",
"otherAttributes", "....",
"child": [{
"_id": "YYYY01",
"otherAttributes", "....",
"grandChild": [{
"_id": "ZZZZ01",
"otherAttributes", "...."
}]
}]
}
Using raw mongo dialect, the below are achievable:
Insert root
db.collection.findAndModify({
query: { "_id": "XXXX01" },
update: {
"_id": "XXXX01",
"otherAttributes", "....",
"child": [{
"_id": "YYYY01",
"otherAttributes", "....",
"grandChild": [{
"_id": "ZZZZ01",
"otherAttributes", "...."
}]
}]
},
upsert: true
})
But a similar findAndReplace with mongoTemplate eg.
var document = new Document();
mongoTemplate.getConverter().write(javaObjectRepresentingTheDocument, document);
update = Update.fromDocument(document) // Primary because I dont want to set each field individually
query.addCriteria(
Criteria.where("id").is("XXXX01")
);
mongoTemplate.findAndModify(query, update,
FindAndModifyOptions.options().upsert(true).returnNew(true),
javaObjectRepresentingTheDocument.getClass(),
collection
)
results in the below error:
Caused by: java.lang.IllegalArgumentException: Invalid BSON field name _id
at org.bson.AbstractBsonWriter.writeName(AbstractBsonWriter.java:534) ~[bson-4.4.3.jar:na]
...
The reason I would want to use findAndReplace over upsert is:
- I need the current object
- Generalize code ie. the same method(
findAndReplace) is useful for both insertion and updation at all levels viz. the root document, a nested document eg.child, a deeply nested document eg.grandChild
I have been successful is getting the same work for child and grandChild nested documents by using
update.addToSet("$[parentSelector]", javaObjectRepresentingTheNestedDocument)
.filterArray(Criteria.where("parentSelector._id").is(<parentSelectorValue>))
but not being able to the get the same working for the root document. Can someone provide some guidance?