skip to Main Content

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
      ]
    ]
  }
]

2

Answers


  1. 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
      ]
    }
    
    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search