$set operator not working as given in the documentation

My original document was like this

`{
    "_id": 1,
    "item": "abc",
    "price": 10,
    "quantity": 2,
    "product": "A"
  },
  {
    "_id": 2,
    "item": "jkl",
    "price": 20,
    "quantity": 1,
    "product": "B"
  }`

I used the below query to swap the product A and B, using the $set and $switch operators

`{$set:{
    "product": { $switch : {
                    branches: [
                      {case : "A", then : "B"},
                      {case : "B", then : "A"},
                    ]
    }}
  }}`

My document got updated like this

`{
    "_id": 1,
    "item": "abc",
    "price": 10,
    "quantity": 2,
    "product": {
      "$switch": {
        "branches": [
          {
            "case": "A",
            "then": "B"
          },
          {
            "case": "B",
            "then": "A"
          }
        ]
      }
    }
  }`

Can any one explain this behaviour? I was expecting a result like below

`{
    "_id": 1,
    "item": "jkl",
    "price": 20,
    "quantity": 1,
    "product": "B"
  }`

Hi @sandeep_s1,

Can you share the full command? I believe it’s working as expected if you’re passing through a document for the update - Refer to the db.collection.updateMany() parameters for more details.

Based off your $set details, the document with _id: 1 should have the item value equal to "abc" still. I assume this might’ve been a typo and your expected output would be the following instead but please correct me if I am wrong since there is no details of the item field value being changed in the update opreation:

[
  { _id: 1, item: 'abc', price: 10, quantity: 2, product: 'B' }, /// <-- 'A' switched with 'B' for document _id: 1
  { _id: 2, item: 'jkl', price: 20, quantity: 1, product: 'A' } /// <-- 'B' switched with 'A' for document _id: 2
]

On my test environment I have the same 2 sample documents:

myFirstDatabase> db.docs.find()
[
  { _id: 1, item: 'abc', price: 10, quantity: 2, product: 'A' },
  { _id: 2, item: 'jkl', price: 20, quantity: 1, product: 'B' }
]

I perform the following updateMany() with the below output:

myFirstDatabase> db.docs.updateMany({},
[
  {
    '$set': {
      product: {
        '$switch': {
          branches: [
            { case: { '$eq': [ '$product', 'A' ] }, then: 'B' },
            { case: { '$eq': [ '$product', 'B' ] }, then: 'A' }
          ]
        }
      }
    }
  }
])
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 2,
  modifiedCount: 2,
  upsertedCount: 0
}
/// Output AFTER the update above
myFirstDatabase> db.docs.find()
[
  { _id: 1, item: 'abc', price: 10, quantity: 2, product: 'B' },
  { _id: 2, item: 'jkl', price: 20, quantity: 1, product: 'A' }
]

Hope this helps.

If you believe this works for you, please test thoroughly on a test environment first to verify it suits all your use case and requirements.

Regards,
Jason

1 Like

@Jason_Tran , the “item” field value is “abc” only its just a typo from my side. My concern was with product field. My expectation was like this

{
    "_id": 1,
    "item": "abc",
    "price": 10,
    "quantity": 2,
    "product": "B"
  }

My query was like this

`db.testCollection.update(
  {},
  { $set: {
    "product": { $switch : {
                    branches: [
                      { case : "A", then : "B" },
                      { case : "B", then : "A" },
                    ]
    }}
  }}
)`

@Jason_Tran , thank you for the correct query. Now it is working.

1 Like

Glad to hear it. FWIW I would refer to the Update Operators documentation to understand why the original query was generating the results you were experiencing.

Thanks for updating this post as well.

Jason

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.