Home > Mobile >  How to use Mongo Aggregation Pipeline to format array?
How to use Mongo Aggregation Pipeline to format array?

Time:09-21

I have this document as part of an Aggregation Pipeline:

[
  {
    "mfe_average": [
      [
        true,
        5.352702824879613
      ],
      [
        false,
        3.2361364317753383
      ],
      [
        null,
        2.675027181819201
      ]
    ]
  }
]

How to convert to this format? Only the true values are Valid.

[
  {
    "mfe_average": [
      [
        "Valid",
        5.352702824879613
      ],
      [
        "Invalid",
        3.2361364317753383
      ],
      [
        "Invalid",
        2.675027181819201
      ]
    ]
  }
]

CodePudding user response:

The query may look complex.

  1. $map - Iterates the element in mfe_average and returns a new array.

    1.1. $concatArrays - Combine arrays into one.

    1.1.1. $cond - Set the value ("Valid"/"Invalid") by getting the first item of the nested array and comparing the value. It results in an array.

    1.1.2. $slice - Take all the values in the nested array except the first item.

db.collection.aggregate([
  {
    $set: {
      mfe_average: {
        $map: {
          input: "$mfe_average",
          as: "avg",
          in: {
            $concatArrays: [
              [
                {
                  $cond: {
                    if: {
                      $eq: [
                        {
                          $arrayElemAt: [
                            "$$avg",
                            0
                          ]
                        },
                        true
                      ]
                    },
                    then: "Valid",
                    else: "Invalid"
                  }
                }
              ],
              {
                $slice: [
                  "$$avg",
                  {
                    $multiply: [
                      {
                        $subtract: [
                          {
                            $size: "$$avg"
                          },
                          1
                        ]
                      },
                      -1
                    ]
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }
])

Demo @ Mongo Playground


If your nested array contains only 2 items, you may not require to write the complex $slice query as above. Instead, just provide -1 to take the last item of the nested array.

{
  $slice: [
    "$$avg",
    -1
  ]
}

CodePudding user response:

You can use $map operator to reconstruct the array,

  • $map to iterate loop of mfe_average array
  • $arrayElemAt to get specific position's element from array
  • $cond to check if the first element is true then return "Valid" otherwise "Invalid"
db.collection.aggregate([
  {
    $addFields: {
      mfe_average: {
        $map: {
          input: "$mfe_average",
          in: [
            {
              $cond: [
                { $arrayElemAt: ["$$this", 0] },
                "Valid",
                "Invalid"
              ]
            },
            { $arrayElemAt: ["$$this", 1] }
          ]
        }
      }
    }
  }
])

Playground

  • Related