Definição
$zipTranspõe uma array de arrays de entrada de modo que o primeiro elemento da array de saída seria uma array contendo, o primeiro elemento da primeira array de entrada, o primeiro elemento da segunda array de entrada etc.
For example,
$zipwould transform[ [ 1, 2, 3 ], [ "a", "b", "c" ] ]into[ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ].$ziptem a seguinte sintaxe:{ $zip: { inputs: [ <array expression1>, ... ], useLongestLength: <boolean>, defaults: <array expression> } } OperandoDescriçãoinputsUma array de expressões que resulta em arrays. Os elementos destes arrays de entrada combinam-se para formar os arrays do array de saída.
If any of the
inputsarrays resolves to a value ofnullor refers to a missing field,$zipreturnsnull.If any of the
inputsarrays does not resolve to an array ornullnor refers to a missing field,$zipreturns an error.useLongestLengthUm booleano que especifica se o comprimento da array mais longa determina o número de arrays na array de saída.
O valor padrão é
false: o menor comprimento da array determina o número de arrays na array de saída.defaultsAn array of default element values to use if the input arrays have different lengths. You must specify
useLongestLength: truealong with this field, or else$zipwill return an error.If
useLongestLength: truebutdefaultsis empty or not specified,$zipusesnullas the default value.If specifying a non-empty
defaults, you must specify a default for each input array or else$zipwill return an error.
Comportamento
The input arrays do not need to be of the same length. By default, the output array has the length of the shortest input array, but the useLongestLength option instructs $zip to output an array as long as the longest input array.
Exemplo | Resultados | |||||||
|---|---|---|---|---|---|---|---|---|
| | |||||||
| | |||||||
| | |||||||
| Porque Isso produz |
Exemplo
Transposição de array
Uma coleção chamada matrices contém os seguintes documentos:
db.matrices.insertMany([ { matrix: [[1, 2], [2, 3], [3, 4]] }, { matrix: [[8, 7], [7, 6], [5, 4]] }, ])
Para calcular a transposição de cada array 3x2 nesta coleção, você pode usar a seguinte operação de agregação:
db.matrices.aggregate([{ $project: { _id: false, transposed: { $zip: { inputs: [ { $arrayElemAt: [ "$matrix", 0 ] }, { $arrayElemAt: [ "$matrix", 1 ] }, { $arrayElemAt: [ "$matrix", 2 ] }, ] } } } }])
Isso retornará as seguintes arrays 2x3:
{ "transposed" : [ [ 1, 2, 3 ], [ 2, 3, 4 ] ] } { "transposed" : [ [ 8, 7, 5 ], [ 7, 6, 4 ] ] }
Filtrando e preservando índices
Você pode usar $zip com $filter para obter um subconjunto de elementos em uma array, salvando o índice original junto com cada elemento retido.
Uma coleção chamada pages contém o seguinte documento:
db.pages.insertOne( { "category": "unix", "pages": [ { "title": "awk for beginners", reviews: 5 }, { "title": "sed for newbies", reviews: 0 }, { "title": "grep made simple", reviews: 2 }, ] } )
O aggregation pipeline a seguir primeiro compactará os elementos da array pages junto com seu índice e, em seguida, filtrará somente as páginas com pelo menos uma avaliação:
db.pages.aggregate([{ $project: { _id: false, pages: { $filter: { input: { $zip: { inputs: [ "$pages", { $range: [0, { $size: "$pages" }] } ] } }, as: "pageWithIndex", cond: { $let: { vars: { page: { $arrayElemAt: [ "$$pageWithIndex", 0 ] } }, in: { $gte: [ "$$page.reviews", 1 ] } } } } } } }])
Isso retornará o seguinte documento:
{ "pages" : [ [ { "title" : "awk for beginners", "reviews" : 5 }, 0 ], [ { "title" : "grep made simple", "reviews" : 2 }, 2 ] ] }