Datos de colección de MongoDB con múltiples matrices:
{ "_id": ObjectId("61aa6bf1742b00f59b894eb7"), "first": ["abc", "def", "ghi"], "last": ["rst", "uvw", "xyz"], "numb": ["12", "34", "56"] }Salida esperada donde los datos en las matrices deberían estar en este formato:
{ "first": "abc", "last": "rst", "numb": "12" }, { "first": "def", "last": "uvw", "numb": "34" }, { "first": "ghi", "last": "xyz", "numb": "56" }Puede utilizar $zip para "transponer" varias matrices (tantas como desee en realidad):
// { // 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" }Este:
zip s las 3 matrices de modo que los elementos en el mismo índice se agrupen en la misma sub-matriz.
$unwind (explota/aplana) esos subconjuntos.
transforma las matrices resultantes en objetos para ajustarse al formato de salida esperado:
$zip ping (¡otra vez!) las claves que queremos asociar con los valores de la matriz (las claves: ["first", "last", "numb"] y los valores: "$x" )$replaceWith el documento actual con el resultado del $zip . Tenga en cuenta que antes de Mongo 4.2 , puede usar $replaceRoot en lugar de $replaceWith .
Consulta
_id también para saber de qué documento provienen y el índice para ordenar después_id e index para obtener los resultados ordenados como si estuvieran en las matrices *los índices se calculan usando la matriz más grande, para estar seguro, en caso de que ya sepa que todos tienen el mismo tamaño, puede reemplazar el:
{"$max": [{"$size": "$first"}, {"$size": "$last"}, {"$size": "$numb"}]} con el tamaño de cualquier matriz por ejemplo (necesitamos el más grande para trabajar):
{"$size": "$first"}
aggregate( [{"$project": {"data": {"$map": {"input": {"$range": [0, {"$max": [{"$size": "$first"}, {"$size": "$last"}, {"$size": "$numb"}]}]}, "in": {"_id": "$_id", "index": "$$this", "first": {"$arrayElemAt": ["$first", "$$this"]}, "last": {"$arrayElemAt": ["$last", "$$this"]}, "numb": {"$arrayElemAt": ["$numb", "$$this"]}}}}}}, {"$unwind": {"path": "$data"}}, {"$replaceRoot": {"newRoot": "$data"}}, {"$sort": {"_id": 1, "index": 1}}, {"$unset": ["index"]}])