sql >> Database teknologi >  >> NoSQL >> MongoDB

Hvordan ændrer jeg betinget et dokument i mongo?

Ud over at være i stand til at gøre det hele atomisk, er der to slags eksisterende forhold, hvor du ønsker at lave en ændring, og du kan håndtere hver af dem atomisk:

  • Der findes ingen registrering for nøglen
  • Der findes en post for nøglen og dens update_time er ældre end new_time

Opdater en eksisterende post for nøgle:

def update_if_stale(key, new_value, new_time):
    collection.update({'key': key,
                       'update_time': {'$lt': new_time}
                       },
                      {'$set': {'value': new_value,
                                'update_time': new_time
                                }
                       }
                      )

Indsæt hvis en post for nøgle ikke eksisterede før:

def insert_if_missing(key, new_value, new_time):
    collection.update({'key': key},
                      {'$setOnInsert': {'value': new_value,
                                        'update_time': new_time
                                        }
                       },
                      upsert=True
                      )

($setOnInsert blev tilføjet i MongoDB 2.4)

Du kan muligvis sætte dem sammen for at få det, du har brug for, f.eks.:

def update_key(key, new_value, new_time):
    insert_if_missing(key, new_value, new_time)        
    update_if_stale(key, new_value, new_time)

Men afhængigt af, hvilke fjern-/indsæt-tidsskalaer, der kan være mulige i dit system, kan du have brug for flere opkald (opdater/indsæt/opdater) eller andre skænderier.

Til side:Hvis du vil have en registrering, der mangler update_time felt, der skal behandles som en gammel post, der skal opdateres, ændre {'$lt': new_time}} til {'$not': {'$gte': new_time}}



  1. serverinstanspuljen blev ødelagt

  2. Ugyldig indlejret dokumentinstans leveret til et EmbeddedDocumentField ved lagring

  3. Hvordan får man vist dokumentfelter i mongo shell?

  4. Min $or-vælger i et databasetrigger-match-udtryk virker ikke på andet niveau af indlejring, når jeg konfigurerer en databasetrigger