Niet mogelijk met een enkele atomaire update. Ik ben bang dat je een aantal update-bewerkingen zou moeten doen die aan beide voorwaarden voldoen.
Splits de updatelogica op in twee verschillende updatebewerkingen, voor de eerste is het gebruik van de positionele $
operator
om het element in de history
te identificeren gewenste array en de $set
om de bestaande velden bij te werken. Deze bewerking volgt de logica update velden ALS de naam EN de organisatie overeenkomen
Nu zou je de findAndModify()
methode voor deze bewerking omdat het het bijgewerkte document kan retourneren. Standaard bevat het geretourneerde document niet de wijzigingen die zijn aangebracht bij de update.
Dus, gewapend met dit arsenaal, kun je dan je tweede logica onderzoeken in de volgende operatie, d.w.z. update ALS die combinatie van "history.name" en "history.organisation" niet in de array voorkomt . Met deze tweede update-bewerking moet u vervolgens de $push
operator om de elementen toe te voegen.
Het volgende voorbeeld demonstreert het bovenstaande concept. In eerste instantie wordt ervan uitgegaan dat u het querygedeelte en het document als afzonderlijke objecten moet bijwerken.
Neem bijvoorbeeld wanneer we documenten hebben die overeenkomen met de bestaande geschiedenisarray, het slechts een enkele updatebewerking uitvoert, maar als de documenten niet overeenkomen, dan is de findAndModify()
methode zal null retourneren, gebruik deze logica in uw tweede update-bewerking om het document naar de array te pushen:
var doc = {
"name": "Test123",
"organisation": "Rat"
}, // document to update. Note: the doc here matches the existing array
query = { "email": "[email protected]" }; // query document
query["history.name"] = doc.name; // create the update query
query["history.organisation"] = doc.organisation;
var update = db.users.findAndModify({
"query": query,
"update": {
"$set": {
"history.$.name": doc.name,
"history.$.organisation": doc.organisation
}
}
}); // return the document modified, if there's no matched document update = null
if (!update) {
db.users.update(
{ "email": query.email },
{ "$push": { "history": doc } }
);
}
Na deze bewerking voor documenten die overeenkomen, levert het opvragen van de collectie hetzelfde op
db.users.find({ "email": "[email protected]" });
Uitvoer:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
}
]
}
Overweeg nu documenten die niet overeenkomen:
var doc = {
"name": "foo",
"organisation": "bar"
}, // document to update. Note: the doc here does not matches the current array
query = { "email": "[email protected]" }; // query document
query["history.name"] = doc.name; // create the update query
query["history.organisation"] = doc.organisation;
var update = db.users.findAndModify({
"query": query,
"update": {
"$set": {
"history.$.name": doc.name,
"history.$.organisation": doc.organisation
}
}
}); // return the document modified, if there's no matched document update = null
if (!update) {
db.users.update(
{ "email": query.email },
{ "$push": { "history": doc } }
);
}
Deze collectie opvragen voor dit document
db.users.find({ "email": "[email protected]" });
zou opleveren
Uitvoer:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
},
{
"name" : "foo",
"organisation" : "bar"
}
]
}