Home >Backend Development >Golang >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!
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 }
I want an updatemany query to update all documents with "results" containing:
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 ? }, }, }}, }}, }
is it possible? I haven't found much information about internal/embedded queries.
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>, ... }, ... }
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' }] }, }, }, }, }, ] );
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"}}, }, }, }, }, }, }
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!