Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.
Menu Docs

$unwind (estágio de agregação )

$unwind

Desconstrói um campo de array a partir dos documentos de entrada para gerar um documento para cada elemento. Cada documento de saída é o documento de entrada com o valor do campo de array substituído pelo elemento.

Você pode utilizar o $unwind para implantações hospedadas nos seguintes ambientes:

  • MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
  • MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB

  • MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB

Você pode passar um operando de caminho do campo ou um operando de documento para desdobrar um campo de array.

You can pass the array field path to $unwind. When using this syntax, $unwind does not output a document if the field value is null, missing, or an empty array.

{ $unwind: <field path> }

Quando você especifica o caminho do campo, prefixe o nome do campo com um sinal de dólar $ e coloque entre aspas.

You can pass a document to $unwind to specify various behavior options.

{
$unwind:
{
path: <field path>,
includeArrayIndex: <string>,
preserveNullAndEmptyArrays: <boolean>
}
}
Campo
Tipo
Descrição

string

Caminho do campo para um campo de array. Para especificar um caminho do campo, prefixe o nome do campo com um sinal de dólar $ e coloque entre aspas.

string

Opcional. O nome de um novo campo para manter o índice da array do elemento. O nome não pode começar com um sinal de dólar $.

booleano

Opcional.

  • Se true, se path estiver ausente ou for uma array vazia, $unwind omite o campo de saída do documento de saída. Se o valor for null, o campo permanecerá null.

  • Se false, se path for nulo, ausente ou uma array vazia, $unwind não gerará um documento.

O valor padrão é false.

Quando o valor em path não resulta em uma array, $unwind se comporta da seguinte maneira:

  • Se o valor não estiver ausente, não null, e não for uma array vazia, $unwind gerará um único documento usando o valor como está.

  • Se includeArrayIndex for especificado, o índice será 0 para entradas de array e null para entradas que não sejam de array. Documentos mais tarde na lista têm um índice maior que 0.

  • If the value is missing, null, or an empty array, $unwind follows the preserveNullAndEmptyArrays option. When includeArrayIndex is specified and the document is preserved, the index is null.

If you specify a path for a field that does not exist in an input document or the field is an empty array, $unwind, by default, ignores the input document and will not output documents for that input document.

Para gerar documentos onde o campo de array está ausente, nulo ou uma array vazia, use a opção preserveNullAndEmptyArrays.

In mongosh, create a sample collection named inventory with the following document:

db.inventory.insertOne({ _id: 1, item: "ABC1", sizes: [ "S", "M", "L"] })

The following aggregation uses the $unwind stage to output a document for each element in the sizes array:

db.inventory.aggregate( [ { $unwind : "$sizes" } ] )

A operação retorna os seguintes resultados:

{ _id: 1, item: "ABC1", sizes: "S" }
{ _id: 1, item: "ABC1", sizes: "M" }
{ _id: 1, item: "ABC1", sizes: "L" }

Cada documento é uma cópia exata documento de entrada, exceto pelo valor do campo sizes agora apresentando um array baseado no valor sizes original.

Considere a collection clothing:

db.clothing.insertMany([
{ _id: 1, item: "Shirt", sizes: [ "S", "M", "L"] },
{ _id: 2, item: "Shorts", sizes: [ ] },
{ _id: 3, item: "Hat", sizes: "M" },
{ _id: 4, item: "Gloves" },
{ _id: 5, item: "Scarf", sizes: null }
])

$unwind treats the sizes field as a single element array if:

  • o campo está presente,

  • o valor não for nulo, e

  • o valor não é um array vazio.

Expand the sizes arrays with $unwind:

db.clothing.aggregate( [ { $unwind: { path: "$sizes" } } ] )

The $unwind operation returns:

{ _id: 1, item: 'Shirt', sizes: 'S' },
{ _id: 1, item: 'Shirt', sizes: 'M' },
{ _id: 1, item: 'Shirt', sizes: 'L' },
{ _id: 3, item: 'Hat', sizes: 'M' }
  • In document "_id": 1, sizes is a populated array. $unwind returns a document for each element in the sizes field.

  • No documento, "_id": 3, sizes for resolvido para uma array de elemento único.

  • Documentos "_id": 2, "_id": 4 e "_id": 5 não retornam nada porque o campo sizes não pode ser reduzido a uma única array de elementos.

Observação

The { path: <FIELD> } syntax is optional. The following $unwind operations are equivalent.

db.clothing.aggregate( [ { $unwind: "$sizes" } ] )
db.clothing.aggregate( [ { $unwind: { path: "$sizes" } } ] )

The preserveNullAndEmptyArrays and includeArrayIndex examples use the following collection:

db.inventory2.insertMany([
{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: [ "S", "M", "L"] },
{ _id: 2, item: "EFG", price: Decimal128("120"), sizes: [ ] },
{ _id: 3, item: "IJK", price: Decimal128("160"), sizes: "M" },
{ _id: 4, item: "LMN" , price: Decimal128("10") },
{ _id: 5, item: "XYZ", price: Decimal128("5.75"), sizes: null }
])

The following $unwind operation uses the preserveNullAndEmptyArrays option to include documents whose sizes field is null, missing, or an empty array.

db.inventory2.aggregate( [
{ $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }
] )

A saída inclui os documentos onde o campo sizes é nulo, ausente ou uma array vazia:

{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: "S" }
{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: "M" }
{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: "L" }
{ _id: 2, item: "EFG", price: Decimal128("120") }
{ _id: 3, item: "IJK", price: Decimal128("160"), sizes: "M" }
{ _id: 4, item: "LMN", price: Decimal128("10") }
{ _id: 5, item: "XYZ", price: Decimal128("5.75"), sizes: null }

The following $unwind operation uses the includeArrayIndex option to include the array index in the output.

db.inventory2.aggregate( [
{
$unwind:
{
path: "$sizes",
includeArrayIndex: "arrayIndex"
}
}])

A operação desenrola a array sizes e inclui o índice da array no novo campo arrayIndex. Se o campo sizes não resolver para uma array preenchida, mas não estiver ausente, nulo ou uma array vazia, o campo arrayIndex será null.

{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: "S", arrayIndex: Long(0) }
{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: "M", arrayIndex: Long(1) }
{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: "L", arrayIndex: Long(2) }
{ _id: 3, item: "IJK", price: Decimal128("160"), sizes: "M", arrayIndex: null }

In mongosh, create a sample collection named inventory2 with the following documents:

db.inventory2.insertMany([
{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: [ "S", "M", "L"] },
{ _id: 2, item: "EFG", price: Decimal128("120"), sizes: [ ] },
{ _id: 3, item: "IJK", price: Decimal128("160"), sizes: "M" },
{ _id: 4, item: "LMN" , price: Decimal128("10") },
{ _id: 5, item: "XYZ", price: Decimal128("5.75"), sizes: null }
])

O pipeline a seguir desenrola a array sizes e agrupa os documentos resultantes pelos valores de tamanho de desenrolamento:

db.inventory2.aggregate( [
// First Stage
{
$unwind: { path: "$sizes", preserveNullAndEmptyArrays: true }
},
// Second Stage
{
$group:
{
_id: "$sizes",
averagePrice: { $avg: "$price" }
}
},
// Third Stage
{
$sort: { "averagePrice": -1 }
}
] )
Primeiro estágio:

The $unwind stage outputs a new document for each element in the sizes array. The stage uses the preserveNullAndEmptyArrays option to include in the output those documents where sizes field is missing, null or an empty array. This stage passes the following documents to the next stage:

{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: "S" }
{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: "M" }
{ _id: 1, item: "ABC", price: Decimal128("80"), sizes: "L" }
{ _id: 2, item: "EFG", price: Decimal128("120") }
{ _id: 3, item: "IJK", price: Decimal128("160"), sizes: "M" }
{ _id: 4, item: "LMN", price: Decimal128("10") }
{ _id: 5, item: "XYZ", price: Decimal128("5.75"), sizes: null }
Segundo estágio:

A etapa $group agrupa os documentos por sizes e calcula o preço médio de cada tamanho. Este estágio passa os seguintes documentos para o próximo estágio:

{ _id: "S", averagePrice: Decimal128("80") }
{ _id: "L", averagePrice: Decimal128("80") }
{ _id: "M", averagePrice: Decimal128("120") }
{ _id: null, averagePrice: Decimal128("45.25") }
Terceiro estágio:

O estágio $sort classifica os documentos por averagePrice em ordem decrescente. A operação retorna o seguinte resultado:

{ _id : "M", averagePrice: Decimal128("120") }
{ _id : "L", averagePrice: Decimal128("80") }
{ _id : "S", averagePrice: Decimal128("80") }
{ _id : null, averagePrice: Decimal128("45.25") }

In mongosh, create a sample collection named sales with the following documents:

db.sales.insertMany( [
{
_id: "1",
items: [
{
name: "pens",
tags: [ "writing", "office", "school", "stationary" ],
price: Decimal128("12.00"),
quantity: Int32("5")
},
{
name: "envelopes",
tags: [ "stationary", "office" ],
price: Decimal128("19.95"),
quantity: Int32("8")
}
]
},
{
_id: "2",
items: [
{
name: "laptop",
tags: [ "office", "electronics" ],
price: Decimal128("800.00"),
quantity: Int32("1")
},
{
name: "notepad",
tags: [ "stationary", "school" ],
price: Decimal128("14.95"),
quantity: Int32("3")
}
]
}
])

A operação a seguir agrupa os itens vendidos por suas marcações e calcula o valor total de vendas por cada marcação.

db.sales.aggregate([
// First Stage
{ $unwind: "$items" },
// Second Stage
{ $unwind: "$items.tags" },
// Third Stage
{
$group:
{
_id: "$items.tags",
totalSalesAmount:
{
$sum: { $multiply: [ "$items.price", "$items.quantity" ] }
}
}
}
])
Primeira etapa

The first $unwind stage outputs a new document for each element in the items array:

{ _id: "1", items: { name: "pens", tags: [ "writing", "office", "school", "stationary" ], price: Decimal128("12.00"), quantity: 5 } }
{ _id: "1", items: { name: "envelopes", tags: [ "stationary", "office" ], price: Decimal128("19.95"), quantity: 8 } }
{ _id: "2", items: { name: "laptop", tags: [ "office", "electronics" ], price: Decimal128("800.00"), quantity": 1 } }
{ _id: "2", items: { name: "notepad", tags: [ "stationary", "school" ], price: Decimal128("14.95"), quantity: 3 } }
Segunda etapa

The second $unwind stage outputs a new document for each element in the items.tags arrays:

{ _id: "1", items: { name: "pens", tags: "writing", price: Decimal128("12.00"), quantity: 5 } }
{ _id: "1", items: { name: "pens", tags: "office", price: Decimal128("12.00"), quantity: 5 } }
{ _id: "1", items: { name: "pens", tags: "school", price: Decimal128("12.00"), quantity: 5 } }
{ _id: "1", items: { name: "pens", tags: "stationary", price: Decimal128("12.00"), quantity: 5 } }
{ _id: "1", items: { name: "envelopes", tags: "stationary", price: Decimal128("19.95"), quantity: 8 } }
{ _id: "1", items: { name: "envelopes", tags: "office", "price" : Decimal128("19.95"), quantity: 8 } }
{ _id: "2", items: { name: "laptop", tags: "office", price: Decimal128("800.00"), quantity: 1 } }
{ _id: "2", items: { name: "laptop", tags: "electronics", price: Decimal128("800.00"), quantity: 1 } }
{ _id: "2", items: { name: "notepad", tags: "stationary", price: Decimal128("14.95"), quantity: 3 } }
{ _id: "2", items: { name: "notepad", "ags: "school", price: Decimal128("14.95"), quantity: 3 } }
Terceiro estágio

O estágio $group agrupa os documentos pela tag e calcula o valor total de vendas de itens com cada tag:

{ _id: "writing", totalSalesAmount: Decimal128("60.00") }
{ _id: "stationary", totalSalesAmount: Decimal128("264.45") }
{ _id: "electronics", totalSalesAmount: Decimal128("800.00") }
{ _id: "school", totalSalesAmount: Decimal128("104.85") }
{ _id: "office", totalSalesAmount: Decimal128("1019.60") }

Para saber mais sobre métodos relacionados, consulte os guias $group, $sum e $multiply.

To see how to use $unwind in a full example, see the Unwind Arrays and Group Data tutorial.