Home > Mobile >  mongoDB $concat string with array item
mongoDB $concat string with array item

Time:09-29

This is my collection:

[
  {
    "_id": {
      "$oid": "6332dda58121948311cbdb67"
    },
    "date": "2022-09-13",
    "file": "xxx",
    "package": 1,
    "userList": [
      {
        "userName": "user_1",
        "crDate": "2022.09.28",
        "boolId": 1
      }
    ]
  },
  {
    "_id": {
      "$oid": "6332dda58121948311cbdb68"
    },
    "date": "2022-09-13",
    "file": "xxx",
    "package": 2,
    "userList": []
  }
]

My desired output would be this (if all of the userList array is empty):

[
  {
    "_id": "2022-09-13",
    "items": [
      {
        "fileName": "xxx",
        "items": [
          {
            "package": "1 - na" 
          },
          {
            "package": "2 - na" 
          }
        ]
      }
    ]
  }
]

And this if I would have an object inside the userList array:

[
  {
    "_id": "2022-09-13",
    "items": [
      {
        "fileName": "xxx",
        "items": [
          {
            "package": "1 - user_1" 
          },
          {
            "package": "2 - na" 
          }
        ]
      }
    ]
  }
]

I try to run this aggregate:

db.collection.aggregate([
  {
    $group: {
      _id: {
        "date": "$date",
        "file": "$file",
        
      },
      "items": {
        $push: {
          "package": {
            $concat: [
              {
                $toString: "package"
              },
              " - ",
              {
                $toString: {
                  $arrayElemAt: [
                    "$userList",
                    0
                  ]
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $group: {
      _id: "$_id.date",
      "items": {
        $push: {
          "fileName": "$_id.file",
          "items": "$items"
        }
      }
    },
    
  },
  
])

It's running if the userList array is empty, but it's not returning the desired output and if the userList array is not empty it throws this error:

Mongo Server error (MongoCommandException): Command failed with error 241 (ConversionFailure): 'Unsupported conversion from object to string in $convert with no one rror value' on server 

Here comes an example: mongo_playground

How should I modify the aggregate?

CodePudding user response:

It requires 2 fixes in the first $group stage,

  • missed the $ sign in package property name, in { $toString: "$package" }
  • use property name userName while accessing first element in $userList.userName
  • use $ifNull operator to check if the property is not present then it returns "na" string
db.collection.aggregate([
  {
    $group: {
      _id: {
        "date": "$date",
        "file": "$file"
      },
      "items": {
        $push: {
          "package": {
            $concat: [
              { $toString: "$package" }, // <====== here 
              " - ",
              {
                $toString: {
                  $ifNull: [
                    { $arrayElemAt: ["$userList.userName", 0] },  // <====== here 
                    "na"
                  ]
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $group: {
      _id: "$_id.date",
      "items": {
        $push: {
          "fileName": "$_id.file",
          "items": "$items"
        }
      }
    }
  }
])

Playground

  • Related