0

I have a sample document with an array of objects

[
  { 
    array_a: [{"key1": "val1", "key2": "val2", "key3": null}, ...],
    array_b: [{"key4": "val1", "key5": null, "key6": null}, ...]
  }, 
  ... 
]

How can I remove the keys with the value null? To become:

[
  { 
    array_a: [{"key1": "val1", "key2": "val2"}, ...],
    array_b: [{"key4": "val1"}, ...]
  }, 
  ... 
]

1 Answer 1

1

A bit long query.

  1. $set

    1.1. (array_a) $map - Iterate array from 1.1.1 and return new array.

    1.1.1. input - $map - Convert each document in array_a to key-value pair array: [{ k: "key1", v: "val1" }].

    1.1.2. $filter - Filter the document (key-value pair) with v is not null.

    1.2. (array_b) Same explanation with 1.1.

  2. $set

    2.1. (array_a) $filter

    2.1.1 input - $map - Iterate each array document in the array to return an array with object.

    2.1.2 cond - Filter the document which is not empty document {}.

    2.2. (array_b) - Same explanation with 2.1.

db.collection.aggregate([
  {
    $set: {
      "array_a": {
        $map: {
          input: {
            $map: {
              input: "$array_a",
              in: {
                $objectToArray: "$$this"
              }
            }
          },
          in: {
            $filter: {
              input: "$$this",
              as: "kv",
              cond: {
                $ne: [
                  {
                    "$getField": {
                      "field": "v",
                      "input": "$$kv"
                    }
                  },
                  null
                ]
              }
            }
          }
        }
      },
      "array_b": {
        $map: {
          input: {
            $map: {
              input: "$array_b",
              in: {
                $objectToArray: "$$this"
              }
            }
          },
          in: {
            $filter: {
              input: "$$this",
              as: "kv",
              cond: {
                $ne: [
                  {
                    "$getField": {
                      "field": "v",
                      "input": "$$kv"
                    }
                  },
                  null
                ]
              }
            }
          }
        }
      }
    }
  },
  {
    $set: {
      "array_a": {
        $filter: {
          input: {
            $map: {
              input: "$array_a",
              in: {
                $arrayToObject: "$$this"
              }
            }
          },
          cond: {
            $ne: [
              "$$this",
              {}
            ]
          }
        }
      },
      "array_b": {
        $filter: {
          input: {
            $map: {
              input: "$array_b",
              in: {
                $arrayToObject: "$$this"
              }
            }
          },
          cond: {
            $ne: [
              "$$this",
              {}
            ]
          }
        }
      }
    }
  }
])

Sample Mongo Playground

Note: The $set stages can combine into one, separate into multiple stages for better readable.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks and my bad. I made the edit to original post. The solution here is almost perfect. If I edit the documents in mongo playground, I still have issue. Rather than removing the entire object, I'd like to remove just the field that is null. Here is the updated one: mongoplayground.net/p/w5pSZ4ukS-m
Thinking you can refer to this demo. I will update the answer once back.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.