MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

mongodb $addToSet към поле без масив при актуализиране при upsert

Това, което се опитвате да направите тук, е да добавите нов елемент към масив само там, където елементът не съществува, и също така да създадете нов документ, където не съществува. Вие избирате $addToSet защото искате артикулите да са уникални, но всъщност наистина искате те да са уникални само с „a“.

Така че $addToset няма да направи това и по-скоро трябва да "тествате" присъстващия елемент. Но истинският проблем тук е, че не е възможно едновременно да се направи това и да се „изкриви“. Логиката не може да работи, тъй като ще бъде създаден нов документ, когато елементът на масива не бъде намерен, вместо да се добавя към елемента на масива, както искате.

Грешките в текущата операция по дизайн като $addToSet не може да се използва за "създаване" на масив, а само за "добавяне" на членове към съществуващ масив. Но както вече беше посочено, вие имате други проблеми с постигането на логиката.

Това, от което се нуждаете тук, е последователност от операции за актуализиране, всяка от които се „опитва“ да изпълни очакваното си действие. Това може да се направи само с множество изрази:

// attempt "upsert" where document does not exist
// do not alter the document if this is an update
db.test.update(
    { "name": "abc" },
    { "$setOnInsert": { "config": [{ "a": 1, "b": 2 }] }},
    { "upsert": true }
)

// $push the element where "a": 1 does not exist
db.test.update(
    { "name": "abc", "config.a": { "$ne": 1 } },
    { "$push": { "config": { "a": 1, "b": 2 } }}
)

// $set the element where "a": 1 does exist
db.test.update(
    { "name": "abc", "config.a": 1 },
    { "$set": { "config.$.b": 2 } }
)

При първа итерация първият израз ще "премести" документа и ще създаде масива с елементи. Вторият израз няма да съответства на документа, тъй като елементът "a" има зададената стойност. Третият оператор ще съответства на документа, но няма да го промени при операция за запис, тъй като стойностите не са променени.

Ако сега промените входа на "b": 3 получавате различни отговори, но желания резултат:

db.test.update(
    { "name": "abc" },
    { "$setOnInsert": { "config": [{ "a": 1, "b": 3 }] }},
    { "upsert": true }
)

db.test.update(
    { "name": "abc", "config.a": { "$ne": 1 } },
    { "$push": { "config": { "a": 1, "b": 3 } }}
)

db.test.update(
    { "name": "abc", "config.a": 1 },
    { "$set": { "config.$.b": 3 } }
)

Така че сега първото изявление съвпада с документ с "name": "abc" но не прави нищо, тъй като единствените валидни операции са върху "вмъкване". Второто твърдение не съвпада, защото "а" отговаря на условието. Третият оператор съвпада със стойността на "a" и променя "b" в съответстващия елемент на желаната стойност.

Впоследствие промяната на "a" на друга стойност, която не съществува в масива, позволява както на 1, така и на 3 да не правят нищо, но вторият оператор добавя друг член към масива, запазвайки съдържанието уникално чрез техните ключове "a".

Също така изпращането на извлечение без промени от съществуващите данни ще доведе до отговор, който казва, че нищо не е променено във всички акаунти.

Така си правите операциите. Можете да направите това с "ordered" Group операции, така че да има само една заявка и отговор от сървъра с валиден отговор за модифициран или създаден.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB:Възможно ли е да се ограничат резултатите от $lookup до определени полета (като проекция)?

  2. node.js:Mongodb db.collection.find() не работи, докато collection.insert работи

  3. Как да изпълнявате необработени команди mongoDB с помощта на mongoose?

  4. SQL изглед в mongodb

  5. Как преброявате количеството документи в колекция MongoDB в рамките на Node?