Definição
$zipNovidade na versão 3.4.
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,
$ziptransformaria[ [ 1, 2, 3 ], [ "a", "b", "c" ] ]em[ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ].$ziptem a seguinte sintaxe:{ $zip: { inputs: [ <array expression1>, ... ], useLongestLength: <boolean>, defaults: <array expression> } } OperandoDescriçãoinputsUma 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
inputsarrays resultar em um valor denullou se referir a um campo ausente,$zipnullretornará.Se qualquer uma das
inputsarrays não resulta em uma array ounullnem se referir a um campo ausente, retornará um$ziperro.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.defaultsUma array de valores de elemento padrão para utilizar se os arrays de entrada tiverem comprimentos diferentes. Você deve especificar
useLongestLength: truejunto com esse campo, caso contrário, retornará um$ziperro.Se
useLongestLength: truemasdefaultsestiver vazio ou não for especificado,$zipusaránullcomo valor padrão.Se especificar um não
defaultsvazio, você deverá especificar um padrão para cada array de entrada, caso contrário retornará um$ziperro.
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.save( { "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 ] ] }