MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Mise à jour simultanée des éléments de tableau qui sont des documents intégrés dans MongoDB

Le processus ici est vraiment très simple, il ne varie que dans l'endroit où vous voulez "trouver ou créer" les éléments dans le tableau.

Tout d'abord, en supposant que les éléments de chaque clé sont déjà en place, le cas simple consiste à interroger l'élément et à le mettre à jour avec l'index renvoyé via le positionnel $ opérateur :

db.collection.update(
   {
       "_id": docId, 
       "attrs": { "$elemMatch": { "key": "A1", "type": "T1" } }
   }
   { "$set": { "attrs.$.value": "20" }
)

Cela ne modifiera que l'élément correspondant sans affecter les autres.

Dans le second cas où "rechercher ou créer" est requis et que la clé particulière peut ne pas exister, vous utilisez alors "deux" instructions de mise à jour. Mais l'API d'opérations en masse permet de le faire en une seule requête au serveur avec une seule réponse :

var bulk = db.collection.initializeOrderedBulkOp();

// Try to update where exists
bulk.find({
    "_id": docId,
    "attrs": { "$elemMatch": { "key": "A1", "type": "T2" } }
}).updateOne({
    "$set": { "attrs.$.value": "30" }
});

// Try to add where does noes not exist
bulk.find({
    "_id": docId,
    "attrs": { "$not": { "$elemMatch": { "key": "A1", "type": "T2" } } }
}).updateOne({
    "$push": { "attrs": { "key": "A1", "type": "T2", "value": "30" } }
});

bulk.execute();

La logique de base étant que la tentative de mise à jour est d'abord effectuée pour faire correspondre un élément avec les valeurs requises, comme cela a été fait auparavant. L'autre condition teste où l'élément n'est pas trouvé du tout en inversant la logique de correspondance avec $not .

Dans le cas où l'élément de tableau n'a pas été trouvé, un nouveau est valide pour être ajouté via $push .

Je devrais vraiment ajouter que puisque nous recherchons spécifiquement des correspondances négatives ici, c'est toujours une bonne idée de faire correspondre le "document" que vous avez l'intention de mettre à jour par un identifiant unique tel que le _id clé. Bien que cela soit possible avec les mises à jour "multi", vous devez faire attention à ce que vous faites.

Ainsi, dans le cas de l'exécution du processus "trouver ou créer", l'élément qui n'a pas été mis en correspondance est ajouté correctement au tableau, sans interférer avec d'autres éléments, la mise à jour précédente pour une correspondance attendue est également appliquée de la même manière :

{
    "_id" : ObjectId("55b570f339db998cde23369d"),
    "attrs" : [
            {
                    "key" : "A1",
                    "type" : "T1",
                    "value" : "20"
            },
            {
                    "key" : "A2",
                    "type" : "T2",
                    "value" : "14"
            },
            {
                    "key" : "A1",
                    "type" : "T2",
                    "value" : "30"
            }
    ]
}

Il s'agit d'un modèle simple à suivre, et bien sûr, les opérations en bloc ici suppriment toute surcharge impliquée en envoyant et en recevant plusieurs requêtes vers et depuis le serveur. Tout cela fonctionne heureusement sans interférer avec d'autres éléments qui peuvent ou non exister.

En plus de cela, il y a les avantages supplémentaires de conserver les données dans un tableau pour une requête et une analyse faciles, comme le permettent les opérateurs standard, sans avoir besoin de revenir au traitement du serveur JavaScript pour parcourir les éléments.