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:""},
{
field1:"value",
field2:"value",
Comment:""}]
Code:
$project: {
someArray: {
$filter: {
input: "$someArray", as: "array",
cond: { $ne: [ "$$array.Comment", ""]}}}}
CodePudding user response:
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.
CodePudding user response:
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'
}
}
}
}
}
}
},
])
CodePudding user response:
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"
}
}
}
}
}
}
])