sql >> Databáze >  >> NoSQL >> MongoDB

MongoDB:upsert dílčí dokument

Ne, na tohle opravdu není lepší řešení, tak snad s vysvětlením.

Předpokládejme, že máte na místě dokument, který má strukturu, jakou ukazujete:

{ 
  "name": "foo", 
  "bars": [{ 
       "name": "qux", 
       "somefield": 1 
  }] 
}

Pokud provedete aktualizaci takto

db.foo.update(
    { "name": "foo", "bars.name": "qux" },
    { "$set": { "bars.$.somefield": 2 } },
    { "upsert": true }
)

Pak je vše v pořádku, protože byl nalezen odpovídající dokument. Ale pokud změníte hodnotu "bars.name":

db.foo.update(
    { "name": "foo", "bars.name": "xyz" },
    { "$set": { "bars.$.somefield": 2 } },
    { "upsert": true }
)

Pak dojde k selhání. Jediná věc, která se zde skutečně změnila, je to, že v MongoDB 2.6 a vyšší je chyba o něco stručnější:

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"
    }
})

To je v některých ohledech lepší, ale stejně se ve skutečnosti nechcete "upsertovat". Co chcete udělat, je přidat prvek do pole, kde "name" aktuálně neexistuje.

Takže to, co opravdu chcete, je „výsledek“ pokusu o aktualizaci bez příznaku „upsert“, abyste zjistili, zda byly ovlivněny nějaké dokumenty:

db.foo.update(
    { "name": "foo", "bars.name": "xyz" },
    { "$set": { "bars.$.somefield": 2 } }
)

Výtěžnost v reakci:

WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })

Takže když jsou upravené dokumenty 0 pak víte, že chcete vydat následující aktualizaci:

db.foo.update(
    { "name": "foo" },
    { "$push": { "bars": {
        "name": "xyz",
        "somefield": 2
    }}
)

Opravdu neexistuje žádný jiný způsob, jak dělat přesně to, co chcete. Protože přidání do pole není striktně "set" typem operace, nemůžete použít $addToSet v kombinaci s funkcí "hromadné aktualizace", takže můžete "kaskádovat" své požadavky na aktualizaci.

V tomto případě se zdá, že musíte zkontrolovat výsledek nebo jinak přijmout čtení celého dokumentu a zkontrolovat, zda se má aktualizovat nebo vložit nový prvek pole do kódu.



  1. Redis publish-subscribe:Je zaručeno, že Redis doručí zprávu i při velkém stresu?

  2. Zálohování a obnovení MongoDB

  3. node.js mongodb vybrat dokument podle _id node-mongodb-native

  4. Jaké bezpečnostní mechanismy má Meteor?