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

Jak implementuji tuto operaci dotazu a aktualizace mongodb (ovladač CSharp)?

Pokud v podstatě chápu vaši podstatu, v podstatě to chcete

  1. Vytáhněte položku, která není vyžadována, z pole referencí
  2. Nastavte hodnotu pole hlavní reference na první prvek změněného pole

A to vše v rámci jedné aktualizace bez přesouvání dokumentů po drátě.

Ale to se bohužel udělat nedá. Hlavním problémem je, že neexistuje způsob, jak odkazovat na hodnotu jiného pole v dokumentu, který se aktualizuje. Přesto, abyste to provedli bez opakování, museli byste také získat přístup k změněným pole, abyste získali nový první prvek.

Možná je jedním z přístupů přehodnotit své schéma, abyste dosáhli toho, co chcete. Moje možnost by trochu rozšířila vaše referenční dokumenty a odstranila potřebu pole hlavní reference.

Zdá se, že předpoklad, se kterým jste ochotni žít s aktualizacemi, je ten, že pokud odstraněná reference byla hlavní reference, můžete novou hlavní referenci nastavit na první prvek v poli. S ohledem na to zvažte následující strukturu:

refs: [ { oid: "object1" }, { oid: "object2" }, { oid: "object5", main: true } ]

Změnou na dokumenty s oid vlastnost, která by byla nastavena na ObjectId, dává možnost mít v dokumentu další vlastnost, která určuje, která je výchozí. To lze snadno zjistit, které ID je hlavní odkaz.

Nyní také zvažte, co by se stalo, kdyby byl z pole vytažen dokument odpovídající "object5" v poli oid:

refs: [ { oid: "object1" }, { oid: "object2" } ]

Když se tedy zeptáte, která je main-reference podle dřívější logiky přijímáte první dokument v poli. Nyní samozřejmě k požadavkům vaší aplikace, pokud chcete nastavit jiný main-reference stačí změnit dokument

refs: [ { oid: "object1" }, { oid: "object2", main: true } ]

A nyní zůstává logikou vybrat prvek pole, který má hlavní vlastnost, protože přednost by se vyskytoval jako true, a jak je ukázáno výše, pokud tato vlastnost neexistuje v žádném dokumentu prvků, vraťte se zpět k prvnímu prvku.

Po tom všem se vaše operace vytažení všech odkazů na objekt z tohoto pole ve všech dokumentech stává docela jednoduchou, jak se to dělá v shellu (stejný formát by měl v podstatě platit pro jakýkoli ovladač):

db.books.update(
   { "refs.oid": "object5" },
   { $pull: { refs: {oid: "object5"} } }, false, true )

Dva další argumenty pro operaci dotazu a aktualizace jsou upsert a multi respektive. V tomto případě upsert nedává moc smysl, protože chceme pouze upravovat dokumenty, které existují, a multi znamená, že chceme aktualizovat vše, co odpovídalo. Výchozí nastavení je změnit pouze první dokument.

Přirozeně jsem zkrátil celý zápis, ale samozřejmě hodnoty mohou být skutečné ObjectId podle vašeho záměru. Zdálo se také rozumné předpokládat, že vaše hlavní použití main-reference je, jakmile dokument načtete. Definování dotazu, který vrací main-reference dodržením logiky, která byla nastíněna, by to mělo být možné, ale jak to vypadá, napsal jsem toho sem hodně a musím si dát pauzu na večeři :)

Domnívám se, že toto představuje cenný případ pro přehodnocení schématu, abyste se vyhnuli opakovaným iteracím toho, čeho chcete dosáhnout.




  1. Mongo dokument JSON -> JSON -> BSON

  2. Transakce MongoDB 4.0:ACID čtení + zápis?

  3. Zmatená terminologie Mongoose/Mongo. Jsou Sub-Docs/Embedded-Docs také kolekcemi?

  4. Souběžnost – Získání MongoDB generovaného ID objektu vloženého přes Java způsobem bezpečným pro vlákna