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

MongoDB:преместване на поддокумент

Не, всъщност няма по-добро решение за това, така че може би с обяснение.

Да предположим, че имате документ, който има структурата, както показвате:

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

Ако направите такава актуализация

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

Тогава всичко е наред, защото е намерен съвпадащ документ. Но ако промените стойността на "bars.name":

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

Тогава ще получите провал. Единственото нещо, което наистина се промени тук, е, че в MongoDB 2.6 и по-нова версия грешката е малко по-сбита:

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

Това е по-добре в някои отношения, но така или иначе наистина не искате да се "разстройвате". Това, което искате да направите, е да добавите елемента към масива, където "name" в момента не съществува.

Така че това, което наистина искате, е „резултатът“ от опита за актуализиране без флага „upsert“, за да видите дали някакви документи са били засегнати:

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

Отстъпка в отговор:

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

Така че, когато модифицираните документи са 0 тогава знаете, че искате да издадете следната актуализация:

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

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

В този случай изглежда, че трябва да проверите резултата или да приемете по друг начин да прочетете целия документ и да проверите дали да актуализирате или вмъкнете нов елемент от масива в кода.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Преброяване на групи с MongoDB, използвайки рамка за агрегиране

  2. Име на полето batchSize се игнорира в Field Projection

  3. Преобразуване на низ в ObjectID в MongoDB

  4. Възможно ли е да се получат полетата в реда на проекция в Aggregation Frameworks mongo

  5. Каква е ползата от Jade или Handlebars при писане на AngularJs приложения