0

I have the JSON below in mongodb collection

{
  "Id":"3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "allowedNssaiList": [
    {
      "allowedSnssaiList": [
        {
          "allowedSnssai": {
            "sst": 1,
            "sd": "2"
          },
          "IMSI": "244340000000001",
          "tac": "3022"
        }
      ],
      "accessType": "3GPP_ACCESS"
    }
  ]
}

I would like to append to the sub array allowedSnssaiList with the object

        {
          "allowedSnssai": {
            "sst": 1,
            "sd": "2"
          },
          "IMSI": "244340000000001",
          "tac": "3022"
        }

I have tried with the following

selector := bson.M{"_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"}
PushToArray := bson.M{"$addToSet": bson.M{"allowedSnssaiList": bson.M{"allowedSnssai": bson.M{"sst": 3,"sd": "4"}, "IMSI": "244510000000004","tac": "3022"}}}

err := db.C(COLLECTION).Update(selector, PushToArray)

but when i push, it does not append well, i get

{
  "_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "allowedNssaiList": [
    {
      "allowedSnssaiList": [
        {
          "allowedSnssai": {
            "sst": 1,
            "sd": "2"
          },
          "IMSI": "244340000000001",
          "tac": "3022"
        }
      ],
      "accessType": "3GPP_ACCESS"
    }
  ],
  "allowedSnssaiList" : [
        {
            "allowedSnssai" : {
                "sst" : 1,
                "sd" : "5"
            },
            "IMSI" : "244340000000005",
            "tac" : "3022"
        }
    ]
}

but i want the result or append as

{
  "_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "allowedNssaiList": [
    {
      "allowedSnssaiList": [
        {
          "allowedSnssai": {
            "sst": 1,
            "sd": "2"
          },
          "IMSI": "244340000000001",
          "tac": "3022"
        },
        {
                "allowedSnssai" : {
                    "sst" : 1,
                    "sd" : "5"
                },
                "IMSI" : "244340000000005",
                "tac" : "3022"
            }
      ],
      "accessType": "3GPP_ACCESS"
    }
  ]
}

Even changing to

PushToArray := bson.M{"$addToSet": bson.M{"allowedNssaiList[0].allowedSnssaiList[0]": bson.M{"allowedSnssai": bson.M{"sst": 3,"sd": "4"}, "IMSI": "244510000000004","tac": "3022"}}}

still does not work. Any help about how to achieve my result.

Thanks for the answer below, i was able to append to the right array as wanted however, i would like to modify any of objects appended to the array so i added an extra field ssid as an id for each object as

{
  "_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "allowedNssaiList": [
    {
      "allowedSnssaiList": [
        {
          "allowedSnssai": {
            "sst": 1,
            "sd": "2"
          },
          "IMSI": "244340000000001",
          "tac": "3022",
           "ssid":1
        },
        {
                "allowedSnssai" : {
                    "sst" : 1,
                    "sd" : "5"
                },
                "IMSI" : "244340000000005",
                "tac" : "3022",
                "ssid":2
            }
      ],
      "accessType": "3GPP_ACCESS"
    }
  ]
}

To modify or update the values for the object with ssid = 2, i have

selector := bson.M{"_id": "3ca85f64-5717-4562-b3fc-2c963f66af33",
        "allowedNssaiList.allowedSnssaiList.ssid": 2}

UpdateArray := bson.M{"$set": bson.M{"allowedNssaiList.0.allowedSnssaiList.$": bson.M{"allowedSnssai": bson.M{"sst": 1,
        "sd": "1000"}, "IMSI": "244340000000010","tac": "302332", "ssid": "2"}}}

err := db.C(COLLECTION).Update(selector, UpdateArray)

this result in updating the object with ssid = 1 but changes the other object as well to ssid = 1 as below. I would also like to delete a specific object as well using the ssid value. Any help.

{
                    "ssid" : 1,
                    "allowedSnssai" : {
                        "sst" : 1,
                        "sd" : "1000"
                    },
                    "IMSI" : "244340000000010",
                    "tac" : "302332"
                },
                {
                    "allowedSnssai" : {
                        "sst" : 1,
                        "sd" : "2"
                    },
                    "IMSI" : "244340000000001",
                    "tac" : "3022",
                    "zone" : "zone3",
                    "ssid" : 1
                }

Any help as how to achieve this. Is using $set right?

daniel wilson
  • 35
  • 1
  • 7
  • 1
    I am not familiar with go but I would try `bson.M{"$addToSet": bson.M{"allowedNssaiList.allowedSnssaiList.": ...` – Wernfried Domscheit Feb 05 '20 at 09:43
  • This does not work either. – daniel wilson Feb 05 '20 at 12:25
  • Note that the object that you gave as example to append (after the `"I would like to append to the sub array allowedSnssaiList with the object"` part) is the same document as the one already present in `allowedSnssaiList`. That's relevant because `$addToSet` will only insert if the document is not present in the array. In the go code example you try to add a new one, which is the one expected I guess :) If you want to append elements even if they already exist you would need to use the `$push` operator. – SPM Feb 05 '20 at 19:16
  • I would like to append if the document is not present, therefore $addToSet is preferred. – daniel wilson Feb 06 '20 at 09:03

1 Answers1

0

You're trying to append an element into a nested array, hence you need to specify the full "path". In your case you can just use index=0 for allowedNssaiList since you only have one document:

bson.M{"$addToSet": bson.M{"allowedNssaiList.0.allowedSnssaiList"...

I think you're using mgo, but it should be equivalent to the mongo-go-driver:

colLoc := mongoClient.Database("stack").Collection("lists")

selector := bson.M{"_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"}
PushToArray := bson.M{"$addToSet": bson.M{"allowedNssaiList.0.allowedSnssaiList": bson.M{"allowedSnssai": bson.M{"sst": 3, "sd": "4"}, "IMSI": "244510000000004", "tac": "3022"}}}

res, err := colLoc.UpdateOne(
    context.Background(),
    selector,
    PushToArray,
)

If you happened to have more than one document in the top array you would need to use a positional operator, for example the all positional operator $[] (note that the positional $ operator does not seem to like traversing more than one array), or the filtered positional operator $[identifier].

SPM
  • 405
  • 1
  • 5
  • 16
  • This works and i was able to append, however, i would like to at the same time modify any of the appended objects in the array and therefor i use $set to try to modify is but it not working as i explain above – daniel wilson Feb 07 '20 at 13:08
  • Glad it worked :) I believe that the new request is independent from the original question. Would you mind opening a new question with the new request? (only in case it wasn't asked already, of course). Like that it will be easier for someone to answer it and it'll be also more useful for people having the same doubt in the future. – SPM Feb 07 '20 at 14:23
  • I tried to open a new request but could not because the response was "sorry you have reach your question limit ..." – daniel wilson Feb 07 '20 at 14:58
  • Ok... try to open a new question when possible with the document before and after the update. In the meantime, please make sure that the _id is the right one (example and code show two different _id values). Not sure if it's the right statement, but I tried it and it only updated the doc from allowed `SnssaiList` with ssid:1 (updated to 2). Make sure you're looking at the right doc because there's also a new field `zone` not seen anywhere. Look [at this question](https://stackoverflow.com/questions/47225132/update-nested-subdocuments-in-mongodb-with-arrayfilters) regarding your current query – SPM Feb 07 '20 at 15:40