Search code examples
jsonmongodbspring-data-jpaaggregation-frameworkunset

MongoDB $unset If condition is met


Someone colud please help me with this situation?

I have this fake JSON...

[
  {
    "user": {
      "type": "PF",
      "code": 12345,
      "Name": "Darth Vader",
      "currency": "BRL",
      "status": "ACTIVE",
      "localization": "NABOO",
      "createDate": 1627990848665,
      "olderAdress": [
        {
          "localization": "DEATH STAR",
          "status": "BLOCKED",
          "createDate": 1627990848665
        },
        {
          "localization": "TATOOINE",
          "status": "CANCELLED",
          "createDate": 1627990555665
        },
        {
          "localization": "ALDERAAN",
          "status": "INACTIVED",
          "createDate": 1627990555665
        },
        
      ]
    }
  }
]

I would like to remove the field code if the status equals "BLOCKED" or "CANCELLED". I'm using aggregate because I'm doing a lot of things before Practical Example. How can I do that??

I need this result:

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "user": {
      "Name": "Darth Vader",
      "createDate": 1.627990848665e+12,
      "currency": "BRL",
      "localization": "DEATH STAR",
      "status": "BLOCKED",
      "type": "PF"
    }
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "user": {
      "Name": "Darth Vader",
      "createDate": 1.627990555665e+12,
      "currency": "BRL",
      "localization": "TATOOINE",
      "status": "CANCELLED",
      "type": "PF"
    }
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "user": {
      "Name": "Darth Vader",
      "code": 12345,
      "createDate": 1.627990555665e+12,
      "currency": "BRL",
      "localization": "ALDERAAN",
      "status": "INACTIVED",
      "type": "PF"
    }
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "user": {
      "Name": "Darth Vader",
      "code": 12345,
      "createDate": ISODate("2021-09-16T17:36:26.405Z"),
      "currency": "BRL",
      "localization": "NABOO",
      "status": "ACTIVE",
      "type": "PF"
    }
  }
]

Soo...Independent of the name, I will check the status and if you contemplate the condition I will remove the field code.


Solution

  • Query

    • uses a system variable $$REMOVE if a field gets this value its removed
    • so the condition is user.code , keep old value if not "BLOCKED","CANCELLED" , else "$$REMOVE" the field

    Test code here

    db.collection.aggregate([
      {
        "$set": {
          "user.code": {
            "$cond": [
              {
                "$in": [
                  "$user.status",
                  [
                    "BLOCKED",
                    "CANCELLED"
                  ]
                ]
              },
              "$$REMOVE",
              "$user.code"
            ]
          }
        }
      }
    ])
    

    Edit

    The above code checks the user.status but you want remove code or not based onthe user.olderAdress.status (after the unwind) (its 2 fields with same name status)

    Query (add this after the stages you already have)

    Test code

    {
        "$set": {
          "user.code": {
            "$cond": [
              {
                "$in": [
                  "$user.status",
                  [
                    "BLOCKED",
                    "CANCELLED"
                  ]
                ]
              },
              "$$REMOVE",
              "$user.code"
            ]
          }
        }
      }