Menu Docs
Página inicial do Docs
/
Manual do MongoDB
/ / /

$project (agregação)

Nesta página

  • Definição
  • Compatibilidade
  • Sintaxe
  • Comportamento
  • Considerações
  • Exemplos
$project

Passa os documentos com os campos solicitados para o próximo estágio do pipeline. Os campos especificados podem ser campos existentes começando nos documentos de entrada ou campos recém-calculados.

Você pode utilizar o $project 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

O estágio $project tem a seguinte forma de protótipo:

{ $project: { <specification(s)> } }

O $project usa um documento que pode especificar a inclusão de campos, a supressão do campo _id, a adição de novos campos e a redefinição dos valores de campos existentes. Alternativamente, você pode especificar a exclusão de campos.

As especificações de $project vêm nos seguintes formatos:

Formato
Descrição
<field>: <1 or true>
Especifica a inclusão de um campo. Números inteiros diferentes de zero também são tratados como true.
_id: <0 or false>

Especifica a supressão do campo _id.

Para excluir um campo condicionalmente, use a variável REMOVE em vez disso. Para obter detalhes, consulte Excluir campos condicionalmente.

<field>: <expression>

Adiciona um novo campo ou redefine o valor de um campo existente.

Se a expressão avaliar para $$REMOVE, o campo será excluído na saída. Para obter detalhes, consulte Excluir campos condicionalmente.

<field>: <0 or false>

Especifica a exclusão de um campo.

Para excluir um campo condicionalmente, use a variável REMOVE em vez disso. Para obter detalhes, consulte Excluir campos condicionalmente.

Se você especificar a exclusão de um campo diferente de _id, não poderá empregar nenhum outro formulário de especificação $project. Esta restrição não se aplica à exclusão condicional de um campo usando a variável REMOVE.

Consulte também o estágio $unset para excluir campos.

  • O campo _id é, por padrão, incluído nos documentos de saída. Para incluir quaisquer outros campos dos documentos de entrada nos documentos de saída, você deve especificar explicitamente a inclusão no $project.

  • Se você especificar a inclusão de um campo que não existe no documento, $project ignorará a inclusão do campo e não o adicionará ao documento.

Por padrão, o campo _id é incluído nos documentos de saída. Para excluir o campo _id dos documentos de saída, você deve especificar explicitamente a supressão do campo _id em $project..

Se você especificar a exclusão de um campo ou campos, todos os outros campos serão são retornados nos documentos de saída.

{ $project: { "<field1>": 0, "<field2>": 0, ... } } // Return all but the specified fields

Se você especificar a exclusão de um campo diferente de _id, não poderá empregar nenhum outro formulário de especificação $project, ou seja, se você excluir campos, também não poderá especificar a inclusão de campos, redefinir o valor dos campos existentes nem adicionar novos campos. Esta restrição não se aplica à exclusão condicional de um campo usando a variável REMOVE.

Consulte também o estágio $unset para excluir campos.

Você pode usar a variável REMOVE em expressões de agregação para suprimir condicionalmente um campo. Para obter um exemplo, consulte Excluir campos condicionalmente.

Observação

O MongoDB stambém fornece $addFields para adicionar novos campos aos documentos.

Para adicionar um novo campo ou redefinir o valor de um campo existente, especifique o nome do campo e defina seu valor para alguma expressão. Para obter mais informações sobre expressões, consulte Operadores de expressão.

Para definir o valor de um campo diretamente como um literal numérico ou booleano, em vez de definir o campo como uma expressão que se resolve em um literal, use o operador $literal. Caso contrário, $project trata o literal numérico ou booleano como sinalizador para incluir ou excluir o campo.

Ao especificar um novo campo e definir seu valor como o caminho do campo de um campo existente, você pode renomear um campo de forma eficaz.

O estágio $project aceita o uso dos colchetes [] para criar diretamente novos campos de array. Se você especificar campos de array que não existem em um documento, a operação substituirá o null como o valor desse campo. Para ver um exemplo, consulte Projetar novos campos de array..

Você não pode usar um índice de array com o estágio $project. Para obter mais informações, consulte Índices de matriz não são compatíveis.

Ao projetar ou adicionar/redefinir um campo em um documento incorporado, você pode usar a notação de ponto, como em

"contact.address.country": <1 or 0 or expression>

Ou você pode aninhar os campos:

contact: { address: { country: <1 or 0 or expression> } }

Ao aninhar os campos, você não pode usar a notação de ponto dentro do documento incorporado para especificar o campo, por exemplo contact: { "address.country": <1 or 0 or expression> } é inválido.

Não é possível especificar um documento incorporado e um campo dentro desse documento incorporado na mesma projeção.

O estágio $project a seguir falha com um erro Path collision porque tenta projetar o documento contact incorporado e o campo contact.address.country:

{ $project: { contact: 1, "contact.address.country": 1 } }

O erro ocorre independentemente da ordem em que o documento principal e o campo incorporado são especificados. O seguinte $project falha com o mesmo erro:

{ $project: { "contact.address.country": 1, contact: 1 } }

Quando você usa um estágio $project, ele normalmente deve ser o último estágio do pipeline, usado para especificar quais campos devem ser retornados ao cliente.

É improvável que o uso de um estágio $project no início ou no meio de um pipeline para reduzir o número de campos passados para estágios subsequentes melhore o desempenho, pois o banco de dados executa essa otimização automaticamente.

O MongoDB retorna um erro se o estágio $project receber um documento vazio.

Por exemplo, a execução do seguinte pipeline produz um erro:

db.myCollection.aggregate( [ {
$project: { }
} ] )

Você não pode usar um índice de array com o estágio $project. Para obter mais informações, consulte Índices de matriz não são compatíveis.

Considere uma coleção books com o seguinte documento:

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5
}

O estágio $project a seguir inclui apenas os campos _id, title e author nos seus documentos de saída:

db.books.aggregate( [ { $project : { title : 1 , author : 1 } } ] )

A operação resulta no seguinte documento:

{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

O campo _id é sempre incluído por padrão. Para excluir o campo _id dos documentos de saída do estágio $project, especifique a exclusão do campo _id definindo-o como 0 no documento de projeção.

Considere uma coleção books com o seguinte documento:

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5
}

O estágio $project a seguir exclui o campo _id, mas inclui os campos title e author nos seus documentos de saída:

db.books.aggregate( [ { $project : { _id: 0, title : 1 , author : 1 } } ] )

A operação resulta no seguinte documento:

{ "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

Considere uma coleção books com o seguinte documento:

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5,
lastModified: "2016-07-28"
}

O estágio $project a seguir exclui o campo lastModified da saída:

db.books.aggregate( [ { $project : { "lastModified": 0 } } ] )

Consulte também o estágio $unset para excluir campos.

Considere uma coleção books com o seguinte documento:

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5,
lastModified: "2016-07-28"
}

O estágio $project a seguir exclui os campos author.first e lastModified da saída:

db.books.aggregate( [ { $project : { "author.first" : 0, "lastModified" : 0 } } ] )

Como alternativa, você pode aninhar a especificação de exclusão em um documento:

db.bookmarks.aggregate( [ { $project: { "author": { "first": 0}, "lastModified" : 0 } } ] )

Ambas as especificações resultam na mesma saída:

{
"_id" : 1,
"title" : "abc123",
"isbn" : "0001122223334",
"author" : {
"last" : "zzz"
},
"copies" : 5,
}

Consulte também o estágio $unset para excluir campos.

Você pode usar a variável REMOVE em expressões de aggregation para suprimir condicionalmente um campo.

Considere uma coleção books com o seguinte documento:

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5,
lastModified: "2016-07-28"
}
{
"_id" : 2,
title: "Baked Goods",
isbn: "9999999999999",
author: { last: "xyz", first: "abc", middle: "" },
copies: 2,
lastModified: "2017-07-21"
}
{
"_id" : 3,
title: "Ice Cream Cakes",
isbn: "8888888888888",
author: { last: "xyz", first: "abc", middle: "mmm" },
copies: 5,
lastModified: "2017-07-22"
}

O estágio $project a seguir usa a variável REMOVE para excluir o campo author.middle somente se ele for igual a "":

db.books.aggregate( [
{
$project: {
title: 1,
"author.first": 1,
"author.last" : 1,
"author.middle": {
$cond: {
if: { $eq: [ "", "$author.middle" ] },
then: "$$REMOVE",
else: "$author.middle"
}
}
}
}
] )

A operação de aggregation resulta na seguinte saída:

{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }
{ "_id" : 2, "title" : "Baked Goods", "author" : { "last" : "xyz", "first" : "abc" } }
{ "_id" : 3, "title" : "Ice Cream Cakes", "author" : { "last" : "xyz", "first" : "abc", "middle" : "mmm" } }

Dica

Comparação com $addFields

Você pode usar o estágio $addFields ou $project para remover campos de documento . A melhor abordagem depende do seu pipeline e de quanto do documento original você deseja manter.

Para ver um exemplo usando $$REMOVE em um $addFields estágio, consulte remover campos.

Considere uma collection bookmarks com os seguintes documentos:

{ _id: 1, user: "1234", stop: { title: "book1", author: "xyz", page: 32 } }
{ _id: 2, user: "7890", stop: [ { title: "book2", author: "abc", page: 5 }, { title: "book3", author: "ijk", page: 100 } ] }

Para incluir somente o campo title no documento incorporado no campo stop, você pode usar a notação de ponto:

db.bookmarks.aggregate( [ { $project: { "stop.title": 1 } } ] )

Você também pode aninhar a especificação de inclusão em um documento:

db.bookmarks.aggregate( [ { $project: { stop: { title: 1 } } } ] )

Ambas as especificações resultam nos seguintes documentos:

{ "_id" : 1, "stop" : { "title" : "book1" } }
{ "_id" : 2, "stop" : [ { "title" : "book2" }, { "title" : "book3" } ] }

Considere uma coleção books com o seguinte documento:

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5
}

O estágio $project a seguir adiciona os novos campos isbn, lastName e copiesSold:

db.books.aggregate(
[
{
$project: {
title: 1,
isbn: {
prefix: { $substr: [ "$isbn", 0, 3 ] },
group: { $substr: [ "$isbn", 3, 2 ] },
publisher: { $substr: [ "$isbn", 5, 4 ] },
title: { $substr: [ "$isbn", 9, 3 ] },
checkDigit: { $substr: [ "$isbn", 12, 1] }
},
lastName: "$author.last",
copiesSold: "$copies"
}
}
]
)

A operação resulta no seguinte documento:

{
"_id" : 1,
"title" : "abc123",
"isbn" : {
"prefix" : "000",
"group" : "11",
"publisher" : "2222",
"title" : "333",
"checkDigit" : "4"
},
"lastName" : "zzz",
"copiesSold" : 5
}

Por exemplo, se uma collection incluir o seguinte documento:

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "x" : 1, "y" : 1 }

A seguinte operação projeta os campos x e y como elementos em um novo campo myArray:

db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y" ] } } ] )

A operação retorna o seguinte documento:

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1 ] }

Se a especificação da array incluir campos que inexistentes em um documento, a operação substituirá null como valor desse campo.

Por exemplo, considerando o mesmo documento acima, a operação a seguir projeta os campos x, y e um campo $someField inexistente como elementos em um novo campo myArray:

db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y", "$someField" ] } } ] )

A operação retorna o seguinte documento:

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1, null ] }

Você não pode usar um índice de array com o estágio $project. Essa seção mostra um exemplo.

Crie a seguinte coleção do pizzas:

db.pizzas.insert( [
{ _id: 0, name: [ 'Pepperoni' ] },
] )

O exemplo a seguir retorna a pizza:

db.pizzas.aggregate( [
{ $project: { x: '$name', _id: 0 } },
] )

A pizza é retornada na saída do exemplo:

[ { x: [ 'Pepperoni' ] } ]

O exemplo seguinte utiliza um índice de array ($name.0) para tentar retornar a pizza:

db.pizzas.aggregate( [
{ $project: { x: '$name.0', _id: 0 } },
] )

A pizza não é retornada na saída do exemplo:

[ { x: [] } ]

Voltar

$planCacheStats