Home > Software design >  Create a Set only if value exists aggregate mongodb
Create a Set only if value exists aggregate mongodb

Time:04-15

I have a dataset:

[
  {
    "_id": 1,
    "Data": {
      "a": {
        "levela": {
          "fname": "fname",
          "lname": "lname"
        },
        "levelfacility": []
      }
    }
  },
  {
    "_id": 2,
    "Data": {
      "a": {
        "levela": {},
        "levelfacility": [
          {
            "facility": "facility"
          }
        ]
      }
    }
  },
  {
    "_id": 3,
    "Data": {
      "a": {
        "levela": {},
        "levelfacility": []
      }
    }
  }
]

I want to apply an upper case to the values only if exists but when I apply a $set, it just is an empty string if it doesn't exist.

[
  {
    "_id": 1,
    "Data": {
      "a": {
        "levela": {
          "fname": "fname",
          "fnameNORM": "FNAME",
          "lname": "lname"
        },
        "levelfacility": []
      }
    }
  },
  {
    "_id": 2,
    "Data": {
      "a": {
        "levela": {},
        "levelfacility": [
          {
            "facility": "facility",
            "facilityNORM": "FACILITY"
          }
        ]
      }
    }
  },
  {
    "_id": 2,
    "Data": {
      "a": {
        "levela": {},
        "levelfacility": []
      }
    }
  }
]

I want to apply something like a $conditional so I am not left with new fields with the original field doesnt exist

I have tried this for a string

{
    $set: {
      "Data.a.levela.fnameNORM": {
        $cond: {
          if: {
            "$Data.a.levela.fname": {
              $exist: true
            }
          },
          then: {
            $toUpper: "$Data.a.levela.fname"
          },
          else: "$$REMOVE"
        }
      }
    }
  }

I have tried this for an array

{
    $set: {
      "Data.a.levelfacility": {
        $map: {
          input: "$Data.a.levelfacility",
          in: {
            $mergeObjects: [
              "$$this",
              {
                "facilityNORM": {
                  $cond: {
                    if: {
                      "$$this.FacilityName": {
                        $exist: true
                      }
                    },
                    then: {
                      $toUpper: "$$this.FacilityName"
                    },
                    else: "$$REMOVE"
                  }
                }
              }
            ]
          }
        }
      }
    }
  }

CodePudding user response:

You are actually on the right track. Just use $map to handle levelfacility array.

db.collection.aggregate([
  {
    "$addFields": {
      "Data.a.levela": {
        "$cond": {
          "if": {
            $ne: [
              {
                "$ifNull": [
                  "$Data.a.levela.fname",
                  null
                ]
              },
              null
            ]
          },
          "then": {
            "fname": "$Data.a.levela.fname",
            "fnameNORM": {
              "$toUpper": "$Data.a.levela.fname"
            }
          },
          "else": "$Data.a.levela"
        }
      }
    }
  },
  {
    "$addFields": {
      "Data.a.levelfacility": {
        "$map": {
          "input": "$Data.a.levelfacility",
          "as": "lf",
          "in": {
            "$cond": {
              "if": {
                $ne: [
                  {
                    "$ifNull": [
                      "$$lf.facility",
                      null
                    ]
                  },
                  null
                ]
              },
              "then": {
                "facility": "$$lf.facility",
                "facilityNORM": {
                  "$toUpper": "$$lf.facility"
                }
              },
              "else": "$$lf"
            }
          }
        }
      }
    }
  }
])

Here is the Mongo playground for your reference.

  • Related