Nee er is niet echt een betere oplossing voor, dus wellicht met uitleg.
Stel dat u een document heeft dat de structuur heeft zoals u laat zien:
{
"name": "foo",
"bars": [{
"name": "qux",
"somefield": 1
}]
}
Als je zo'n update doet
db.foo.update(
{ "name": "foo", "bars.name": "qux" },
{ "$set": { "bars.$.somefield": 2 } },
{ "upsert": true }
)
Dan is alles in orde omdat er een overeenkomend document is gevonden. Maar als u de waarde van "bars.name" wijzigt:
db.foo.update(
{ "name": "foo", "bars.name": "xyz" },
{ "$set": { "bars.$.somefield": 2 } },
{ "upsert": true }
)
Dan krijg je een mislukking. Het enige dat hier echt is veranderd, is dat in MongoDB 2.6 en hoger de fout iets beknopter is:
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16836,
"errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: bars.$.somefield"
}
})
Dat is in sommige opzichten beter, maar je wilt toch echt niet "upsert". Wat u wilt doen, is het element toevoegen aan de array waar de "naam" momenteel niet bestaat.
Dus wat je echt wilt, is het "resultaat" van de updatepoging zonder de "upsert"-vlag om te zien of er documenten zijn aangetast:
db.foo.update(
{ "name": "foo", "bars.name": "xyz" },
{ "$set": { "bars.$.somefield": 2 } }
)
Toegeven als reactie:
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
Dus wanneer de gewijzigde documenten 0
. zijn dan weet je dat je de volgende update wilt uitgeven:
db.foo.update(
{ "name": "foo" },
{ "$push": { "bars": {
"name": "xyz",
"somefield": 2
}}
)
Er is echt geen andere manier om precies te doen wat je wilt. Aangezien de toevoegingen aan de array niet strikt een "set"-type bewerking zijn, kunt u $addToSet
niet gebruiken gecombineerd met de "bulk update"-functionaliteit daar, zodat u uw updateverzoeken kunt "cascaderen".
In dit geval lijkt het erop dat u het resultaat moet controleren, of anderszins moet accepteren dat u het hele document leest en moet controleren of u een nieuw array-element in de code wilt bijwerken of invoegen.