MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

MongoDB:upsert sub-dokument

Nie, nie ma lepszego rozwiązania tego problemu, więc może z wyjaśnieniem.

Załóżmy, że masz dokument o pokazanej strukturze:

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

Jeśli dokonasz takiej aktualizacji

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

Wtedy wszystko jest w porządku, ponieważ znaleziono pasujący dokument. Ale jeśli zmienisz wartość „bars.name”:

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

Wtedy dostaniesz porażkę. Jedyną rzeczą, która naprawdę się tutaj zmieniła, jest to, że w MongoDB 2.6 i nowszych błąd jest trochę bardziej zwięzły:

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

Pod pewnymi względami jest to lepsze, ale i tak naprawdę nie chcesz się „zwracać”. To, co chcesz zrobić, to dodać element do tablicy, w której „nazwa” obecnie nie istnieje.

Więc to, czego naprawdę chcesz, to „wynik” próby aktualizacji bez flagi „upsert”, aby sprawdzić, czy jakikolwiek dokument został naruszony:

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

Ustępowanie w odpowiedzi:

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

Więc kiedy zmodyfikowane dokumenty mają wartość 0 to wiesz, że chcesz wydać następującą aktualizację:

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

Naprawdę nie ma innego sposobu na zrobienie dokładnie tego, czego chcesz. Ponieważ dodatki do tablicy nie są ściśle "ustawianym" typem operacji, nie można użyć $addToSet w połączeniu z funkcją „zbiorczej aktualizacji”, dzięki czemu można „kaskadowo” przesyłać żądania aktualizacji.

W tym przypadku wydaje się, że musisz sprawdzić wynik lub w inny sposób zaakceptować odczytanie całego dokumentu i sprawdzenie, czy zaktualizować lub wstawić nowy element tablicy w kodzie.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Jak I i NIE w wyszukiwaniu $text w MongoDB

  2. Jak formatować liczby w SQL

  3. Czy warto skracać nazwy właściwości MongoDB?

  4. Sterownik C# dla MongoDb:jak używać limit+liczba?

  5. MongoDB $godzina