I've been trying to flatten a field of array that occasionally has a nested array when its size is 1 as you can see in example below. (This happened due to a previous error I made with updateMany() while trying to put every string in array but somehow, I put the string in a nested array).
This is a Japanese-English dictionary database and "re_pri" stands for reading-priority. Not every, but most documents have this field inside.
I managed to flatten the array with unwind but later I found out that unwind cannot be used with updateMany(). So, I started searching for another way to accomplish this but couldn't find a way so far.
{
"r_ele": [{
"re_pri": [
"ichi1",
"news1",
"nf10"
]}],
},
{
"r_ele": [{
"re_pri": [
[
"ichi1"
]
]
}]
}
I tried setting it to a new field called "a", assigning it to the re_pri
field then unsetting the "a" field. But it didn't work the way I expected.
This is the way I tried with aggregation pipeline
[
{
$match: {
"r_ele.re_pri": {
$exists: 1,
},
},
},
{
$project: {
"r_ele.re_pri": 1,
a: {
$reduce: {
input: "$r_ele.re_pri",
initialValue: [],
in: {
$cond: {
if: {
$and: [
{
$eq: [
{
$type: "$$this",
},
"array",
],
},
{
$eq: [
{
$size: "$$this",
},
1,
],
},
],
},
then: {
$concatArrays: "$$this",
},
else: {
$concatArrays: [
"$$this",
"$$value",
],
},
},
},
},
},
},
},
{
$unwind: "$a",
},
{
$set: {
"r_ele.re_pri": "$a",
},
},
{
$unset: "a",
}
]
this is the output:
{
"a": [
"ichi1",
"news1",
"nf10"
]
},
{
"a": [
[
"ichi1"
]
]
}
But my expectation was:
{
"a": [
"ichi1",
"news1",
"nf10"
]
},
{
"a": [
"ichi1"
]
}
What am I doing wrong?
I don't see any reason for $reduce
. Try this one:
db.collection.aggregate([
{
$project: {
a: {
$cond: {
if: { $eq: [{ $type: { $first: { $first: "$r_ele.re_pri" } } }, "array"] },
then: { $first: { $first: "$r_ele.re_pri" } },
else: { $first: "$r_ele.re_pri" }
}
}
}
}
])