[GODRIVER-780] Filter vs Update Created: 22/Jan/19  Updated: 11/Sep/19  Resolved: 30/Jan/19

Status: Closed
Project: Go Driver
Component/s: CRUD
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Minor - P4
Reporter: PuzzlePuzzling Assignee: Isabella Siu (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I have the following CRUD operation:
 

filter := bson.M{"uuid": user.UUID, "cycles.dailyIntakes": bson.M{"$elemMatch": bson.M{"_id": ID}}}
update := bson.M{"$push": bson.M{"cycles.$.dailyIntakes.$[i].macroNutrients": macroNutrientsWithIDAsString.MacroNutrients}}
optionsArrayFilters := options.ArrayFilters{}
dailyIntakeFilter := bson.M{"i._id": ID}
optionsArrayFilters.Filters = append(optionsArrayFilters.Filters, dailyIntakeFilter)
options := options.UpdateOptions{ArrayFilters: &optionsArrayFilters} 
_, err = collection.UpdateOne(nil, filter, update, &options) 

I had to add array filters. I was under the impression that the filter I pass to the UpdateOne method would first retrieve the document I want based on my filter, and then update that document...

So if I am retrieving one document why is that I can't push like the following line:

update := bson.M{"$push": bson.M{"cycles.0.dailyIntakes.0.macroNutrients": macroNutrientsWithIDAsString.MacroNutrients}}

Notice the 0's.

I believe the 0's represent the index one wants to retrieve from an array. Is that correct?



 Comments   
Comment by PuzzlePuzzling [ 30/Jan/19 ]

Okay, thank you!

This question can be closed.

P.P

Comment by Isabella Siu (Inactive) [ 29/Jan/19 ]

Hi puzzlepuzzling,

Array filters were necessary because the  $ update operator cannot be used for queries that traverse more than one array. It can retrieve the matching cycle array element, but can not retrieve the dailyIntake array element nested inside it.
The line with the 0's would get the macroNutrient element in the first dailyIntakes element from the first cycle for the document, which would not necessarily be the macroNutrient that you want.
For the problem that you mentioned in your comment, please confirm that the server versions and the collection contents are identical locally and on Docker.
Please note that the GODRIVER project is for reporting bug or feature suggestions for the driver. For MongoDB-related support discussion please post on the mongodb-user group or Stack Overflow with the mongodb tag. A question like this involving more discussion would be best posted on the mongodb-users group.

Kind regards,
Isabella

Comment by PuzzlePuzzling [ 29/Jan/19 ]

Something weird is happening, while I am using it locally on my mac with version 4.0.3 works perfectly fine. However, when I download the docker image 4.0.3, the above code no longer works.

I was under the impression since all ids are unique, and by only passing the id that maps to a dailyintake object, I would be able to retrieve the dailyIntake object that needs to be updated. However, I wasn't able to with the docker image. I had to pass both cycleId and dailyIntake id.

My code is now looking like the following:

 

// macronutrients.go file

 
type MacroNutrientsWithIDAsString struct

{     CycleID string `json:"_cycleId" binding:"required"`     DailyID string `json:"_dailyId" bson:"_id" binding:"required"`     MacroNutrients MacroNutrients `json:"macroNutrients" bson:"macroNutrients" binding:"required"` }

 
func AddMacroNutrient(macroNutrientsWithIDAsString MacroNutrientsWithIDAsString, user *User) error

{     collection := getUserCollection()     cycleID, err := primitive.ObjectIDFromHex(macroNutrientsWithIDAsString.CycleID)     dailyID, err := primitive.ObjectIDFromHex(macroNutrientsWithIDAsString.DailyID)     macroNutrientsWithIDAsString.MacroNutrients.ID = primitive.NewObjectID()     filter := bson.M\{"uuid": user.UUID}

    update := bson.M{"$push": bson.M{"cycles.$[i].dailyIntakes.$[j].macroNutrients": macroNutrientsWithIDAsString.MacroNutrients}}

    //options
    //Can I convert a []T to an []interface{}?
    //Not directly. It is disallowed by the language specification because the
    //two types do not have the same representation in memory. It is necessary to copy
    //the elements individually to the destination slice. This example converts a slice of int to a slice of interface{}:
    optionsArrayFilters := options.ArrayFilters{}
    cycleFilter := bson.M{"i._id": cycleID}
    dailyIntakeFilter := bson.M{"j._id": dailyID}
    optionsArrayFilters.Filters = append(optionsArrayFilters.Filters, cycleFilter)
    optionsArrayFilters.Filters = append(optionsArrayFilters.Filters, dailyIntakeFilter)
    options := options.UpdateOptions{ArrayFilters: &optionsArrayFilters}
    _, err = collection.UpdateOne(nil, filter, update, &options)

    if err != nil

{         return err     }

    collection.FindOne(nil, bson.M{"uuid": user.UUID}).Decode(&user)
    return nil
}
When I put in code mode, everything is not well formatted. so I kept it as is.

 

Comment by PuzzlePuzzling [ 29/Jan/19 ]

Yes the following is sample data:

{
    "uuid": "3",
    "cycles": [
        {
            "_id": "5c4695ff4ae7cd621a98303c",
            "startTime": "2019-01-21T23:03:11-05:00",
            "endTime": "2019-01-21T23:03:11-05:00",
            "dailyIntakes": [
                {
                    "_id": "5c46986f626c917da73cae74",
                    "date": "2019-01-21T23:13:35-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c46986f626c917da73cae73",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c489c4056f3758ace4587b9",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        }
                    ]
                },
                {
                    "_id": "5c469876626c917da73cae76",
                    "date": "2019-01-21T23:13:43-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c469876626c917da73cae75",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c46987e626c917da73cae77",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        }
                    ]
                }
            ]
        },
        {
            "_id": "5c4696014ae7cd621a98303d",
            "startTime": "2019-01-21T23:03:13-05:00",
            "endTime": "2019-01-21T23:03:13-05:00",
            "dailyIntakes": [
                {
                    "_id": "5c4696074ae7cd621a98303f",
                    "date": "2019-01-21T23:03:20-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c4696074ae7cd621a98303e",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c469630c3ae2e4d35944ac9",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c469860626c917da73cae72",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c489c3456f3758ace4587b8",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        }
                    ]
                },
                {
                    "_id": "5c489cd08f78f9a4efdc9cd4",
                    "date": "2019-01-23T11:56:49-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c489cd08f78f9a4efdc9cd3",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        }
                    ]
                }
            ]
        },
        {
            "_id": "5c489cbf8f78f9a4efdc9cd2",
            "startTime": "2019-01-23T11:56:32-05:00",
            "endTime": "2019-01-23T11:56:32-05:00",
            "dailyIntakes": [
                {
                    "_id": "5c489ceb8f78f9a4efdc9cd6",
                    "date": "2019-01-23T11:57:16-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c489ceb8f78f9a4efdc9cd5",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        }
                    ]
                }
            ]
        }
    ]
}

 I would like to add the following:

{
    "_id": "5c489ceb8f78f9a4efdc9cd6",
    "macroNutrients": {
        "mealNumber": 1,
        "proteins": "2",
        "carbohydrates": "4",
        "fat": "1"
    }
}

The `_id` in the object I want to store matches the _id inside the list of dailyIntakes.

Therefore the output should be (the update is in the last object):

{
    "uuid": "3",
    "cycles": [
        {
            "_id": "5c4695ff4ae7cd621a98303c",
            "startTime": "2019-01-21T23:03:11-05:00",
            "endTime": "2019-01-21T23:03:11-05:00",
            "dailyIntakes": [
                {
                    "_id": "5c46986f626c917da73cae74",
                    "date": "2019-01-21T23:13:35-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c46986f626c917da73cae73",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c489c4056f3758ace4587b9",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        }
                    ]
                },
                {
                    "_id": "5c469876626c917da73cae76",
                    "date": "2019-01-21T23:13:43-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c469876626c917da73cae75",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c46987e626c917da73cae77",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        }
                    ]
                }
            ]
        },
        {
            "_id": "5c4696014ae7cd621a98303d",
            "startTime": "2019-01-21T23:03:13-05:00",
            "endTime": "2019-01-21T23:03:13-05:00",
            "dailyIntakes": [
                {
                    "_id": "5c4696074ae7cd621a98303f",
                    "date": "2019-01-21T23:03:20-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c4696074ae7cd621a98303e",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c469630c3ae2e4d35944ac9",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c469860626c917da73cae72",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
                        {
                            "_id": "5c489c3456f3758ace4587b8",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        }
                    ]
                },
                {
                    "_id": "5c489cd08f78f9a4efdc9cd4",
                    "date": "2019-01-23T11:56:49-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c489cd08f78f9a4efdc9cd3",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        }
                    ]
                }
            ]
        },
        {
            "_id": "5c489cbf8f78f9a4efdc9cd2",
            "startTime": "2019-01-23T11:56:32-05:00",
            "endTime": "2019-01-23T11:56:32-05:00",
            "dailyIntakes": [
                {
                    "_id": "5c489ceb8f78f9a4efdc9cd6",
                    "date": "2019-01-23T11:57:16-05:00",
                    "macroNutrients": [
                        {
                            "_id": "5c489ceb8f78f9a4efdc9cd5",
                            "mealNumber": 1,
                            "proteins": "1",
                            "carbohydrates": "1",
                            "fat": "1",
                            "status": false
                        },
{"mealNumber": 1, "proteins": "2", "carbohydrates": "4", "fat": "1" }
                    ]
                }
            ]
        }
    ]
}

 

 

Comment by Ian Whalen (Inactive) [ 28/Jan/19 ]

puzzlepuzzling can you give us some sample data that you're trying to query against? As well as what your desired outcome is for the document after the update?

Generated at Thu Feb 08 08:34:57 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.