How to update document using values ​​from internal array

王林
Release: 2024-02-10 11:09:09
forward
862 people have browsed it

How to update document using values ​​from internal array

php editor Banana brings you a practical guide on how to update a document using values ​​in an internal array. During development, we often need to get data from an array and update it into the document. This article will introduce how to use the values ​​in PHP's internal array to update documents. This method is simple and flexible, and can help us handle data update tasks more efficiently. Whether you are a beginner or an experienced developer, I hope this article can bring you some valuable knowledge and tips. Let's get started right away!

Question content

I'm stuck on something that doesn't seem complicated, maybe there's something I didn't think of or didn't see.

Have (many) documents containing arrays of objects, for example:

{
    "_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
}
Copy after login

I want an updatemany query to update all documents with "results" containing:

  • "id":"a1"
  • "somethingelse": "aa"

Increase its "total" by the value of "result" containing "id": "a1" and "somethingelse": "aa"

So in our example: The result for "0x1" contains "id": "a1" and "somethingelse": "aa" has a "value" of 1 -> I want its "total" to increase by 1

The result for "0x2" contains "id": "a1" and "somethingelse": "aa" has a "value" of 44 -> I want its "total" to increase by 44

"0x3" does not meet the conditions

Written in go, starting as follows:

// 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 ?
                },
            },
        }},
    }},
}
Copy after login

is it possible? I haven't found much information about internal/embedded queries.

Solution

db.collection.updatemany(filter, update, options) The update parameter can be an update document or an aggregation pipeline ( doc).

Update documents contain only update operator expressions, which look like this:

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

Values ​​cannot reference fields in the document.

Although the aggregation pipeline is more advanced and can reference fields in the document. Here's one way to do it using an aggregation pipeline:

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' }] },
          },
        },
      },
    },
  ]
);
Copy after login

Translated into go code:

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"}},
                    },
                },
            },
        },
    },
}
Copy after login

The above is the detailed content of How to update document using values ​​from internal array. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!