You can make use of $zip
to "transpose" multiple arrays (as many as you'd like actually):
// {
// first: ["abc", "def", "ghi"],
// last: ["rst", "uvw", "xyz"],
// numb: ["12", "34", "56"]
// }
db.collection.aggregate([
{ $project: { x: { $zip: { inputs: ["$first", "$last", "$numb"] } } } },
// { x: [["abc", "rst", "12"], ["def", "uvw", "34"], ["ghi", "xyz", "56" ]] }
{ $unwind: "$x" },
// { x: [ "abc", "rst", "12" ] }
// { x: [ "def", "uvw", "34" ] }
// { x: [ "ghi", "xyz", "56" ] }
{ $replaceWith: {
$arrayToObject: { $zip: { inputs: [["first", "last", "numb"], "$x"] } }
}}
])
// { first: "abc", last: "rst", numb: "12" }
// { first: "def", last: "uvw", numb: "34" }
// { first: "ghi", last: "xyz", numb: "56" }
This:
zip
s the 3 arrays such that elements at the same index will get grouped into the same sub-array.
$unwind
s (explodes/flattens) those sub-arrays.
transforms the resulting arrays into objects to fit your expected output format:
- by
$zip
ping (again!) the keys we want to associate with the array's values (the keys: ["first", "last", "numb"]
and the values: "$x"
)
- and
$replaceWith
the current document with the result of the $zip
.
Note that prior to Mongo 4.2
, you can use $replaceRoot
instead of $replaceWith
.