Maison  >  Article  >  développement back-end  >  Comment mettre à jour le document en utilisant les valeurs du tableau interne

Comment mettre à jour le document en utilisant les valeurs du tableau interne

王林
王林avant
2024-02-10 11:09:09862parcourir

Comment mettre à jour le document en utilisant les valeurs du tableau interne

éditeur php Banana vous propose un guide pratique sur la façon de mettre à jour un document en utilisant les valeurs d'un tableau interne. Pendant le développement, nous avons souvent besoin d'extraire les données d'un tableau et de les mettre à jour dans le document. Cet article explique comment utiliser les valeurs du tableau interne de PHP pour mettre à jour les documents. Cette méthode est simple et flexible et peut nous aider à gérer plus efficacement les tâches de mise à jour des données. Que vous soyez débutant ou développeur expérimenté, j'espère que cet article pourra vous apporter de précieuses connaissances et conseils. Commençons tout de suite !

Contenu de la question

Je bloque sur quelque chose qui ne semble pas compliqué, il y a peut-être quelque chose auquel je n'ai pas pensé ou que je n'ai pas vu.

Avoir de (nombreux) documents contenant des tableaux d'objets, par exemple :

{
    "_id": "ox1",
    "results": [
        {
            "id": "a1",
            "somethingelse": "aa",
            "value": 1
        },
        {
            "id": "a2",
            "somethingelse": "bb",
            "value": 2
        },
        {
            "id": "a3",
            "somethingelse": "cc",
            "value": 3
        }
    ],
    "total": 0
},
{
    "_id": "ox2",
    "results": [
        {
            "id": "a1",
            "somethingelse": "aa",
            "value": 44
        },
        {
            "id": "a4",
            "somethingelse": "bb",
            "value": 4
        },
        {
            "id": "a5",
            "somethingelse": "aa",
            "value": 5
        }
    ],
    "total": 0
},
{
    "_id": "ox3",
    "results": [
        {
            "id": "a2",
            "somethingelse": "aa",
            "value": 1
        },
        {
            "id": "a3",
            "somethingelse": "aa",
            "value": 4
        },
        {
            "id": "a4",
            "somethingelse": "aa",
            "value": 5
        }
    ],
    "total": 0
}

Je souhaite une requête updatemany pour mettre à jour tous les documents avec des "résultats" contenant :

  • "id": "a1"
  • "quelque chose d'autre": "aa"

Augmentez son "total" de la valeur du "result" contenant "id": "a1" et "somethingelse": "aa"

Donc dans notre exemple : Le résultat pour "0x1" contient "id": "a1" et "somethingelse": "aa" a une "valeur" de 1 -> Je veux que son "total" augmente de 1

Le résultat pour "0x2" contient "id": "a1" et "somethingelse": "aa" a une "valeur" de 44 -> Je veux que son "total" augmente de 44

"0x3" ne remplit pas les conditions

Écrit en go, ça commence comme ça :

// Here I filter only the documents meeting the condition
filter := bson.D{{
    Key: "results,
    Value: bson.D{{
        Key: "$elemMatch",
        Value: bson.D{
            {Key: "id", Value: "a1"},
            {Key: "somethingElse", Value: "aa"},
        }},
    }},
}

// This is where it gets tricky
addTotal := bson.M{
    "$set": bson.D{{
        Key: "total",
        Value: bson.D{{
            Key: "$sum",
            Value: bson.A{
                "$total",
                bson.M{ 
                    // How can I get the "value" from the right object from the array ?
                },
            },
        }},
    }},
}

Est-ce possible ? Je n'ai pas trouvé beaucoup d'informations sur les requêtes internes/intégrées.

Workaround

db.collection.updatemany(filter, update, options) 中的 update Le paramètre peut être un document de mise à jour ou un pipeline d'agrégation (doc).

Les documents de mise à jour contiennent uniquement des expressions d'opérateur de mise à jour, qui ressemblent à ceci :

{
   <operator1>: { <field1>: <value1>, ... },
   <operator2>: { <field2>: <value2>, ... },
   ...
}

Les valeurs ne peuvent pas référencer des champs dans le document.

Bien que le pipeline d'agrégation soit plus avancé et puisse référencer des champs dans le document. Voici une façon de procéder à l'aide d'un pipeline d'agrégation :

db.collection.updatemany(
  { results: { $elemmatch: { id: 'a1', somethingelse: 'aa' } } },
  [
    {
      $set: {
        total: {
          $let: {
            vars: {
              items: {
                $filter: {
                  input: '$results',
                  as: 'item',
                  cond: {
                    $and: [
                      { $eq: ['$$item.id', 'a1'] },
                      { $eq: ['$$item.somethingelse', 'aa'] },
                    ],
                  },
                },
              },
            },
            in: { $add: ['$total', { $sum: '$$items.value' }] },
          },
        },
      },
    },
  ]
);

Traduit en code go :

filter := bson.M{
    "results": bson.M{
        "$elemMatch": bson.M{
            "id":            "a1",
            "somethingElse": "aa",
        },
    },
}

vars := bson.M{
    "items": bson.M{
        "$filter": bson.M{
            "input": "$results",
            "as":    "item",
            "cond": bson.M{
                "$and": bson.A{
                    bson.M{"$eq": bson.A{"$$item.id", "a1"}},
                    bson.M{"$eq": bson.A{"$$item.somethingElse", "aa"}},
                },
            },
        },
    },
}

update := bson.A{
    bson.M{
        "$set": bson.M{
            "total": bson.M{
                "$let": bson.M{
                    "vars": vars,
                    "in": bson.M{
                        "$add": bson.A{"$total", bson.M{"$sum": "$$items.value"}},
                    },
                },
            },
        },
    },
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer