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

Zaktualizuj tablicę tam, gdzie istnieje lub wstaw nowy element tablicy

Chcesz .bulkWrite() dla tego. W rzeczywistości nie jest to pojedyncza operacja, więc chcesz przesłać wiele operacji w jednym żądaniu. Zasadniczo spróbuj napisać aktualizację za pomocą $set gdzie istnieją dane lub $push nowe dane tam, gdzie nie istnieją:

db.collection.bulkWrite([
  { "updateOne": {
    "filter": { "_id": "1", "option.weight": "10" },
    "update": { 
      "$set": { "option.$.price": "30" }
    }
  }},
  { "updateOne": {
    "filter": { "_id": "1", "option.weight": { "$ne": "10" } },
    "update": {
      "$push": { "option": { "weight": "10", "price": "30" } }
    }
  }}
])

Dodatni przypadek to po prostu wartość, a $ne „neguje” dopasowanie równości, co oznacza, że ​​element nie istnieje. Oczywiście pozycyjny $ operator jest używany z $set gdzie to robi

Biorąc pod uwagę dane, tylko jedna z operacji będzie pasować i zostanie zastosowana jako aktualizacja, mimo że dwie operacje są wysyłane w „paczce”.

Jeśli chcesz „upserts” również dla całego dokumentu, musisz na końcu dodać kolejną operację. Pamiętaj, że nie możesz zastosować „upsert” jako opcji w żadnej z pozostałych instrukcji, zwłaszcza $ne ponieważ spowodowałoby to utworzenie nowego dokumentu, w którym element tablicy nie istnieje, a nie tylko _id :

db.collection.bulkWrite([
  { "updateOne": {
    "filter": { "_id": "1", "option.weight": "10" },
    "update": { 
      "$set": { "option.$.price": "30" }
    }
  }},
  { "updateOne": {
    "filter": { "_id": "1", "option.weight": { "$ne": "10" } },
    "update": {
      "$push": { "option": { "weight": "10", "price": "30" } }
    }
  }},
  { "updateOne": {
    "filter": { "_id": 1 },
    "update": {
      "$setOnInsert": {
        "option": [
           { "weight": "10", "price": "30" }
         ]
      }
    },
    "upsert": true
  }}
])

$setOnInsert jest tutaj główną pomocą, poza tą ostatnią operacją, która jest jedyną oznaczoną jako "upsert" . Ta kombinacja zapewnia, że ​​tam, gdzie zostanie znaleziony podstawowy „dokument”, tak naprawdę nic się nie dzieje, ale gdy nie zostanie znaleziony, dodawany jest nowy element tablicy.

Na marginesie, zdecydowanie sugerowałbym przechowywanie wartości liczbowych jako liczb, a nie ciągów. W większości przypadków nie tylko oszczędza miejsce, ale także jest o wiele bardziej przydatny w ten sposób.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Pobierz wartość z MongoDB według jej nazwy klucza

  2. MongoDB rejestruje wszystkie zapytania

  3. Nie można połączyć się z MongoDB przez PHP

  4. Czy Spring Data MongoDb obsługuje operator agregacji tablic $filter?

  5. Jak używać fetchNewObject z update.one ReactiveMongo?