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?
2
Answers
The input
$r_ele.re_pri
to your$reduce
operator, is an array of arrays. For your second document, the input is essentially,You are checking if the element is an array of size 1, and then concatenating that array.
Instead, you should be concatenating just the element of that array.
Try this,
Demo
I don’t see any reason for
$reduce
. Try this one: