Upserting subdocumets as a list with mutate_in

Hello gurus,
Would really appreciate your help here.

I am trying to mutate the sub documents by using mutate_in and then defining the SD with a path for each element that I want to put in.

The code looks like this:

cb.mutate_in(‘1_2’,
SD.upsert(
‘strat.a’, 76543, create_parents=True),
SD.upsert(
‘strat.b’, “true”, create_parents=True),
SD.upsert(
‘strat.c’, 30, create_parents=True),
SD.upsert(
‘strat.d’, -25, create_parents=True),
SD.upsert(
‘strat.e’, “C”, create_parents=True),
SD.upsert(
‘strat.f’, 7, create_parents=True),
)

This is the kind of result it brings in:

{
“strat”: {
“a”: 76543,
“b”: “true”,
“c”: 30,
“d”: -25,
“e”: “C”,
“f”: 7
}
}

What I am looking for is this (Notice that I am putting that in a list here):

{
“Strat”: [
{
“a”: “12345”,
“b”: 7,
“c”: “C”,
“d”: “true”,
“e”: -25,
“f”: 25
}
]
}

Once I am able to achieve the above as a list, I should be able to generate multiple sub documents like this:
Notice that now I have 2 elements in this list both having different values:

{
“Strat”: [
{
“a”: “12345”,
“b”: 7,
“c”: “C”,
“d”: “true”,
“e”: -25,
“f”: 25
},
{
“a”: “34567”,
“b”: 8,
“c”: “F”,
“d”: “false”,
“e”: -30,
“f”: 40
}
]
}

QUESTION:

  1. can I achieve this with mutate_in and SD.upsert ?
  2. if so, how can I change that code I have provided at the beginning of this thread to put things in a list
  3. Once I can put it as a list, how can I avoid upsert not overwriting the record but to attach another record in that list?

Your help is highly appreciated. Thank you !

Looking forward to some direction from all the couchbase gurus out there

@sreeharsha27 let me attempt to see if I can help.
Did you try visit this part of the document and try the array append and prepend to see if you can get what you need ?

1 Like

@AV25242 thanks for getting back on this. Yes, I did visit that document and was not able to use that for my requirement. I am not sure if I used it exactly the way it should be used.

Upsert is giving me what I want but couldn’t get results exactly in the same way that I showed in my example

Did you try something like this ? assuming you are using Python SDK 2.x ? and assuming your document structure is like you had explained. Similar code exists for 3.0
bucket.upsert(‘Strats’, ) // creates an empty array , thats open and close square brackets it renders as a box on the screen
bucket.mutate_in(‘Strats’,
SD.array_append(‘a’, ‘76543’),
SD.array_append(‘b’, ‘true’). … etc

1 Like

Will certainly try and get back to you. thanks @AV25242

Hello @AV25242, I highly appreciate your help.
this is what I did according to your suggestion and it worked to a certain degree.

cb.upsert('strats', [])
cb.mutate_in('1_2',              
         SD.array_append(
'strats.a', 67324, create_parents=True), 
         SD.array_append(
'strats.b', "true", create_parents=True),
         SD.array_append(
'strats.c', 30, create_parents=True),
         SD.array_append(
'strats.d', -25, create_parents=True),
         SD.array_append(
'strats.e', "C", create_parents=True),             
         ) 

It generated results like this:

{
"strats": {
"a": [67324],
"b": [ "true"],
"c": [30 ],
"d": [-25 ],
"e": ["C"]
  }
}

How I would like my results to be generated is like this. I am not looking to place each object in an element to be a list but in fact placing the entire element in a list. If there are more elements, then those elements in the list are going to be comma separated.

{
"strats": [{
"a":  67324 ,
"b": "true",
"c": 30,
"d":  -25,
"e": "C"
}
  ]
}

were you able to figure this out @sreeharsha27 ?

If not I will seek some help