I have a sample document with 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 null value? To become:
[
{
array_a: [{"key1": "val1", "key2": "val2"}, ...],
array_b: [{"key4": "val1"}, ...]
},
...
]
CodePudding user response:
A bit long query.
$set
1.1. (
array_a
)$map
- Iterate array from 1.1.1 and return new array.1.1.1.
input
-$map
- Convert each document inarray_a
to key-value pair array:[{ k: "key1", v: "val1" }]
.1.1.2.
$filter
- Filter the document (key-value pair) withv
is notnull
.1.2. (
array_b
) Same explanation with 1.1.$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",
{}
]
}
}
}
}
}
])
Note: The $set
stages can combine into one, separate into multiple stages for better readable.