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
]
]
}
]
CodePudding user response:
The query may look complex.
$map
- Iterates the element inmfe_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
]
}
]
}
]
}
}
}
}
}
])
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
]
}
CodePudding user response:
You can use $map
operator to reconstruct the array,
$map
to iterate loop ofmfe_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] }
]
}
}
}
}
])