$zip (agregação)
Nesta página
Definição
$zip
Transpõ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.
Por exemplo,
$zip
transformaria[ [ 1, 2, 3 ], [ "a", "b", "c" ] ]
em[ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]
.$zip
tem a seguinte sintaxe:{ $zip: { inputs: [ <array expression1>, ... ], useLongestLength: <boolean>, defaults: <array expression> } } OperandoDescriçãoinputs
Uma array deexpressões que resulta em arrays. Os elementos destes arrays de entrada combinam-se para formar os arrays do array de saída.
Se qualquer uma das arrays
inputs
resultar em um valor denull
ou se referir a um campo ausente,$zip
retornaránull
.Se qualquer uma das arrays
inputs
não resultar em uma array ounull
nem se referir a um campo ausente,$zip
retornará um erro.useLongestLength
Um 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.defaults
Uma array de valores de elemento padrão para utilizar se os arrays de entrada tiverem comprimentos diferentes. Você deve especificar
useLongestLength: true
junto com esse campo, caso contrário,$zip
retornará um erro.Se
useLongestLength: true
masdefaults
estiver vazio ou não for especificado,$zip
usaránull
como valor padrão.Se especificar um
defaults
não vazio, você deverá especificar um padrão para cada array de entrada, caso contrário$zip
retornará um erro.
Comportamento
As arrays de entrada não precisam ter o mesmo comprimento. Por padrão, a array de saída tem o comprimento da array de entrada mais curta, mas a opção useLongestLength
instrui $zip
a gerar uma array tão longa quanto a array de entrada mais longa.
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 ] ] }