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

pushOrModify jak operator dla poddokumentu mongo

W rzeczywistości wymaga to „dwóch” (lub „trzech” z upsert ) instrukcji aktualizacji i jest jednym z bardzo dobrych powodów, dla których istnieją operacje „luzem”.

db.collection.bulkWrite([
  // Attempt to update the matched element
  { "updateOne": {
    "filter": { 
      "name": "SweetTown",
      "residents.name": "Bob"
    },
    "update": {
      "$set": { "residents.$.reputation": 30 }    
    }
  },
  // $push the element where not matched
  { "updateOne": {
    "filter": {
      "name": "SweetTown",
      "residents.name": { "$ne": "Bob" } 
    },
    "update": { 
      "$push": { 
        "residents": { "name": "Bob", "reputation": 30 } 
      }
    } 
  }}
])

Lub jeśli rzeczywiście chcesz dołączyć "upsert" dla podstawowego dokumentu "SweetTown" następnie musisz oddzielić ten problem do własnego testu:

db.collection.bulkWrite([
  // Attempt to update the matched element
  { "updateOne": {
    "filter": { 
      "name": "SweetTown",
      "residents.name": "Bob"
    },
    "update": {
      "$set": { "residents.$.reputation": 30 }    
    }
  },
  // $push the element where not matched
  { "updateOne": {
    "filter": {
      "name": "SweetTown",
      "residents.name": { "$ne": "Bob" } 
    },
    "update": { 
      "$push": { 
        "residents": { "name": "Bob", "reputation": 30 } 
      }
    } 
  }},
  // Only use $setOnInsert when actually an upsert
  { "updateOne": {
      "filter": {
        "name": "SweetTown"
      },
      "update": {
        "$setOnInsert": {
           "residents": [{ "name": "Bob", "reputation": 30 }]
        }
      },
      "upsert": true
  }}
])

Ogólna koncepcja polega więc na tylko zastosuj $setOnInsert akcja, gdy "upsert" faktycznie występuje. Aby upewnić się, że dzieje się tak tylko w tym przypadku, inne operacje faktycznie patrzące na element tablicy nie są oznaczone "upsert" opcja. Ta część jest celowa.

Niezależnie od tego, jak na to spojrzysz, jest to możliwe tylko dla jednego tych operacji, aby faktycznie dokonać jakiejkolwiek modyfikacji w bazie danych, czy element został znaleziony, czy nie, lub nawet dokument nie został znaleziony i utworzono nowy.

W żadnym wypadku nie jest możliwe wykonanie tego rodzaju operacji w jednej instrukcji aktualizacji. Jednak ponieważ operacje „zbiorcze” to tak naprawdę tylko jedna żądanie z jednym odpowiedź, to jeśli chodzi o twoją aplikację, wystarczyło tylko porozmawiać z serwerem raz aby serwer wypróbował wszystkie te trzy rzeczy i zwrócił odpowiedź.

W przypadku wcześniejszego użycia bezpośredniego interfejsu Bulk API alternatywna składnia to:

var bulk = db.collection.initializeOrderedBulkOp();

// $set matched where existing
bulk.find({ "name": "SweetTown", "residents.name": "Bob" }).updateOne({
  "$set": { "residents.$.reputation": 30 }
});

// $push where not existing
bulk.find({ "name": "SweetTown", "residents.name": { "$ne": "Bob" } }).updateOne({
  "$push": { "residents": { "name": "Bob", "reputation": 30 } }
});

// Attempt to upsert only
bulk.find({ "name": "SweetTown" }).upsert().updateOne({
  "$setOnInsert": {
    "residents": [{ "name": "Bob", "reputation": 30 }]
  }
})

bulk.execute();



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Silnik wykrywania i monitorowania serwerów jest przestarzały

  2. Zapytanie o inny model w metodzie instancji innego modelu

  3. Jak pobrać tylko wybrane identyfikatory mongo za pomocą wiosennej metody mongorepository?

  4. Wartość domyślna nie jest ustawiona podczas używania aktualizacji z Upsert jako true

  5. Wstaw wydajność node-mongodb-native