skip to Main Content

So far, after i tried, i came up with solution where i am able to remove the whole object inside of the array if that object has field with empty value. That does not work in my case. I only need to remove the field and keep rest of the object. In this case, "Comment" field is the one having empty values occasionally. Thanks in advance!

Structure:

someArray: [
    {
      field1:"value",
      field2:"value",
      Comment:"",
      Answer:"",
},
    {
      field1:"value",
      field2:"value",
      Comment:"",
      Answer:"",

}]

Code:

        $project: {
          someArray: {
            $filter: {
              input: "$someArray", as: "array",
              cond: { $ne: [ "$$array.Comment", ""]}}}}

3

Answers


  1. Use $map to loop over the array elements.For each array element where comment is not an empty string, return whole element, otherwise return the document excluding comment field. Like this:

    db.collection.aggregate([
      {
        "$project": {
          someArray: {
            $map: {
              input: "$someArray",
              as: "element",
              in: {
                $cond: {
                  if: {
                    $eq: [
                      "",
                      "$$element.Comment"
                    ]
                  },
                  then: {
                    field1: "$$element.field1",
                    field2: "$$element.field2"
                  },
                  else: "$$element"
                }
              }
            }
          }
        }
      },
      
    ])
    

    Here, is the working link.

    Login or Signup to reply.
  2. Solution from Charchit Kapoor works only if your array has exactly

    {
      field1: ...
      field2: ...
      Comment:""
    }
    

    But it does not work for arbitrary fields. I was looking for more generic solution, my first idea was this:

    db.collection.aggregate([
       {
          "$project": {
             someArray: {
                $map: {
                   input: "$someArray",
                   in: {
                      $cond: {
                         if: { $eq: ["$$this.Comment", ""] },
                         then: { $mergeObjects: ["$$this", { Comment: "$$REMOVE" }] },
                         else: "$$this"
                      }
                   }
                }
             }
          }
       }
    ])
    

    but it does not work.

    I ended on this one:

    db.collection.aggregate([
       {
          "$project": {
             someArray: {
                $map: {
                   input: "$someArray",
                   in: {
                      $cond: {
                         if: { $eq: ["", "$$this.Comment"] },
                         then: {
                            $arrayToObject: {
                               $filter: {
                                  input: {
                                     $map: {
                                        input: { $objectToArray: "$$this" },
                                        as: "element",
                                        in: { $cond: [{ $eq: ["$$element.k", "Comment"] }, null, "$$element"] }
                                     }
                                  },
                                  as: "filter",
                                  cond: "$$filter" // removes null's from array 
                               }
                            }
                         },
                         else: "$$this"
                      }
                   }
                }
             }
          }
       }
    ])
    

    Mongo Playground

    Login or Signup to reply.
  3. Here is a solution where an array’s nested object can have multiple fields and these need not be referred in the aggregation. Removes the nested object’s field with value as an empty string (""):

    db.collection.aggregate([
    { 
      $set: { 
          someArray: { 
              $map: { 
                  input: '$someArray', 
                  as: 'e',
                  in: {
                      $let: {
                          vars: {
                              temp_var: { 
                                  $filter: { 
                                      input: { $objectToArray: '$$e' }, 
                                      cond: { $ne: [ '', '$$this.v' ] }, 
                                  }
                               }
                          },
                          in: {
                              $arrayToObject: '$$temp_var'
                          }
                      }
                  }
              }
          }
       }
    },
    ])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search