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: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
  • 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

Passe um operando de caminho do campo ou um operando de documento para desenrolar um campo de array .

Você pode fornecer o caminho do campo de array para $unwind. Com essa sintaxe, $unwind não gera um documento se o valor do campo for nulo, ausente ou um array vazio.

{ $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.

Você pode passar um documento para $unwind para especificar opções.

{
$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.

  • Se o valor estiver ausente, null ou uma array vazia, $unwind seguirá a opção preserveNullAndEmptyArrays. Quando includeArrayIndex é especificado e o documento é preservado, o índice é null.

Se você indicar um caminho de um campo inexistente ou de um campo vazio no documento de entrada, $unwind, o padrão é que o documento não processe nem emita documentos para esse documento de entrada.

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

Os exemplos nesta página usam dados do conjunto de dados de amostra sample_mflix. Para obter detalhes sobre como carregar esse conjunto de dados em sua implantação autogerenciada do MongoDB , consulte Carregar o conjunto de dados de amostra. Se você fez modificações nos bancos de dados de amostra, talvez seja necessário descartar e recriar os bancos de dados para executar os exemplos nesta página.

A agregação a seguir usa o estágio $unwind para gerar um documento para cada elemento da array genres do documento de filme Inception:

db.movies.aggregate( [
{ $match: { title: "Inception" } },
{ $project: { _id: 0, title: 1, genres: 1 } },
{ $unwind: "$genres" }
] )
[
{
genres: 'Action',
title: 'Inception'
},
{
genres: 'Mystery',
title: 'Inception'
},
{
genres: 'Sci-Fi',
title: 'Inception'
}
]

Cada documento de saída é idêntico ao documento de entrada, exceto pelo valor do campogenres , que agora contém um único elemento da array genres original.

A agregação a seguir usa o estágio $unwind com quatro documentos de filme. Dois dos documentos ("La porta del cielo" e "Neecha Nagar") não têm um campogenres :

db.movies.aggregate( [
{
$match: {
title: {
$in: [
"Inception",
"Brave",
"La porta del cielo",
"Neecha Nagar"
]
}
}
},
{ $project: { _id: 0, title: 1, genres: 1 } },
{ $unwind: { path: "$genres" } }
] )
[
{
genres: 'Animation',
title: 'Brave'
},
{
genres: 'Adventure',
title: 'Brave'
},
{
genres: 'Comedy',
title: 'Brave'
},
{
genres: 'Action',
title: 'Inception'
},
{
genres: 'Mystery',
title: 'Inception'
},
{
genres: 'Sci-Fi',
title: 'Inception'
}
]
  • Nos documentos "Brave" e "Inception", genres é uma array preenchida. $unwind retorna um documento para cada elemento.

  • Os documentos "La porta del cielo" e "Neecha Nagar" não têm um campogenres, portanto, $unwind não retorna nenhum documento para eles.

Observação

A sintaxe { path: <FIELD> } é opcional. As seguintes operações do $unwind são equivalentes.

db.<COLLECTION>.aggregate(
[ { $unwind: "<FIELD>" } ]
)
db.<COLLECTION>.aggregate(
[ { $unwind: { path: "<FIELD>" } } ]
)

Os exemplos preserveNullAndEmptyArrays e includeArrayIndex utilizam documentos da coleção sample_mflix.movies.

A seguinte operação $unwind utiliza a opção preserveNullAndEmptyArrays para incluir documentos cujo campo genres está ausente.

db.movies.aggregate( [
{
$match: {
title: {
$in: [
"Inception",
"Brave",
"La porta del cielo",
"Neecha Nagar"
]
}
}
},
{ $project: { _id: 0, title: 1, genres: 1 } },
{
$unwind: {
path: "$genres",
preserveNullAndEmptyArrays: true
}
}
] )
[
{
title: 'La porta del cielo'
},
{
title: 'Neecha Nagar'
},
{
genres: 'Animation',
title: 'Brave'
},
{
genres: 'Adventure',
title: 'Brave'
},
{
genres: 'Comedy',
title: 'Brave'
},
{
genres: 'Action',
title: 'Inception'
},
{
genres: 'Mystery',
title: 'Inception'
},
{
genres: 'Sci-Fi',
title: 'Inception'
}
]

A seguinte operação $unwind utiliza a opção includeArrayIndex para incluir o índice de array na saída.

db.movies.aggregate( [
{ $match: { title: "Inception" } },
{ $project: { _id: 0, title: 1, genres: 1 } },
{
$unwind: {
path: "$genres",
includeArrayIndex: "genreIndex"
}
}
] )
[
{
genres: 'Action',
title: 'Inception',
genreIndex: Long('0')
},
{
genres: 'Mystery',
title: 'Inception',
genreIndex: Long('1')
},
{
genres: 'Sci-Fi',
title: 'Inception',
genreIndex: Long('2')
}
]

O pipeline a seguir desenrola a array genres e agrupa os documentos resultantes por gênero para contar o número de filmes em cada gênero:

db.movies.aggregate( [
// First Stage
{
$match: {
title: {
$in: [
"The Dark Knight",
"Inception",
"Interstellar",
"Brave"
]
}
}
},
// Second Stage
{ $project: { _id: 0, title: 1, genres: 1 } },
// Third Stage
{ $unwind: "$genres" },
// Fourth Stage
{
$group: {
_id: "$genres",
movieCount: { $sum: 1 }
}
},
// Fifth Stage
{ $sort: { movieCount: -1 } }
] )
[
{
_id: 'Adventure',
movieCount: 2
},
{
_id: 'Action',
movieCount: 2
},
{
_id: 'Drama',
movieCount: 2
},
{
_id: 'Sci-Fi',
movieCount: 2
},
{
_id: 'Crime',
movieCount: 1
},
{
_id: 'Animation',
movieCount: 1
},
{
_id: 'Comedy',
movieCount: 1
},
{
_id: 'Mystery',
movieCount: 1
}
]

Você pode aplicar $unwind várias vezes em um único pipeline para expandir documentos que contenham vários campos de array. A operação a seguir desenrola a array genres e, em seguida, a array cast para produzir um documento plano para cada combinação de ator de gênero e, em seguida, agrupa por gênero para contar o total de aparições do elenco em cada gênero:

db.movies.aggregate( [
// First Stage
{
$match: {
title: {
$in: [ "Inception", "The Dark Knight", "Interstellar" ]
}
}
},
// Second Stage
{ $project: { _id: 0, title: 1, genres: 1, cast: 1 } },
// Third Stage
{ $unwind: "$genres" },
// Fourth Stage
{ $unwind: "$cast" },
// Fifth Stage
{
$group: {
_id: "$genres",
castAppearances: { $sum: 1 }
}
}
] )
[
{
_id: 'Adventure',
castAppearances: 4
},
{
_id: 'Crime',
castAppearances: 4
},
{
_id: 'Action',
castAppearances: 8
},
{
_id: 'Drama',
castAppearances: 8
},
{
_id: 'Mystery',
castAppearances: 4
},
{
_id: 'Sci-Fi',
castAppearances: 8
}
]

Os exemplos de C# nesta página utilizam o banco de dados sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver MongoDB .NET/C#.

A seguinte classe Movie modela os documentos na collection sample_mflix.movies:

public class Movie
{
public ObjectId Id { get; set; }
public int Runtime { get; set; }
public string Title { get; set; }
public string Rated { get; set; }
public List<string> Genres { get; set; }
public string Plot { get; set; }
public ImdbData Imdb { get; set; }
public int Year { get; set; }
public int Index { get; set; }
public string[] Comments { get; set; }
[BsonElement("lastupdated")]
public DateTime LastUpdated { get; set; }
}

Observação

ConventionPack para Pascal Case

As classes C# nesta página usam Pascal case para seus nomes de propriedade, mas os nomes de campo na coleção MongoDB usam Camel case. Para considerar essa diferença, você pode usar o seguinte código para registrar um ConventionPack quando o aplicativo iniciar:

var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);

Para usar o driver MongoDB .NET/C# para adicionar um $unwind estágio a uma agregação pipeline, chame o método Unwind() em um PipelineDefinition objeto.

O exemplo a seguir cria um estágio de pipeline que itera sobre o campo Genres em cada documento de entrada Movie . Para cada valor no campo Genres , o estágio cria um novo documento Movie e preenche seu campo Genres com o valor Genres do documento de entrada.

var pipeline = new EmptyPipelineDefinition<Movie>()
.Unwind(m => m.Genres);

Você pode usar um objeto AggregateUnwindOptions para personalizar o comportamento do método Unwind().

O exemplo a seguir executa a mesma operação que o exemplo anterior, mas também inclui as seguintes opções:

  • PreserveNullAndEmptyArrays garante que documentos que contêm uma array vazia no campo Genres sejam incluídos na saída.

  • A opção IncludeArrayIndex adiciona um novo campo denominado Index a cada documento de saída. O valor deste campo é o índice da array do valor do campo Genres na array Genres do documento de entrada.

var pipeline = new EmptyPipelineDefinition<Movie>()
.Unwind(m => m.Genres,
new AggregateUnwindOptions<Movie>()
{
PreserveNullAndEmptyArrays = true,
IncludeArrayIndex = new ExpressionFieldDefinition<Movie, int>(
m => m.Index)
});

Os exemplos do Node.js nesta página utilizam o banco de dados do sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver do MongoDB Node.js

Para usar o driver Node.js do MongoDB para adicionar um estágio $unwind a um pipeline de agregação , use o operador $unwind em um objeto de pipeline.

O exemplo a seguir cria um estágio de pipeline que itera sobre o campo genres em cada documento de entrada movie . Para cada valor no campo genres , o estágio cria um novo documento movie e preenche seu campo genres com o valor genres do documento de entrada. Em seguida, o exemplo executa o agregação pipeline:

const pipeline = [{ $unwind: "$genres" }];
const cursor = collection.aggregate(pipeline);
return cursor;

Você pode personalizar o comportamento do método $unwind. O exemplo a seguir executa a mesma operação que o exemplo anterior, mas também inclui as seguintes opções:

  • preserveNullAndEmptyArrays garante que documentos que contêm uma array vazia no campo genres sejam incluídos na saída.

  • includeArrayIndex adiciona um novo campo denominado index a cada documento de saída. O campo contém o índice da array do valor genres no campo genres do documento de entrada.

const pipeline = [
{
$unwind: {
path: "$genres",
preserveNullAndEmptyArrays: true,
includeArrayIndex: "index"
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

Para estágios e expressões relacionados, consulte $group, $sum, $sort e $multiply.

Para obter um exemplo completo, consulte o tutorial Desenrole arrays e dados de grupo.