Docs Menu
Docs Home
/ /
Etapas de la pipeline de agregación

$proyecto (agregación)

$project

Pasa los documentos con los campos solicitados a la siguiente etapa en el pipeline. Los campos especificados pueden ser campos existentes de los documentos de entrada o campos recién calculados.

Puedes usar $project para implementaciones alojadas en los siguientes entornos:

  • MongoDB Atlas: El servicio totalmente gestionado para implementaciones de MongoDB en la nube

  • MongoDB Enterprise: La versión basada en suscripción y autogestionada de MongoDB

  • MongoDB Community: La versión de MongoDB con código fuente disponible, de uso gratuito y autogestionada.

La etapa $project tiene la siguiente forma de prototipo:

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

El $project procesa un documento que puede especificar la inclusión de campos, la eliminación del campo _id, la adición de nuevos campos y el restablecimiento de los valores de los campos existentes. Alternativamente, puede especificarse la exclusión de campos.

Las especificaciones tienen las siguientes $project formas:

formulario
Descripción

<field>: <1 or true>

Especifica la inclusión de un campo. Los enteros no nulos también se tratan como true.

_id: <0 or false>

Especifica la eliminación del campo _id.

Para excluir un campo de forma condicional, utiliza la variable REMOVE en su lugar. Para obtener más información, consulta Excluye campos de forma condicional.

<field>: <expression>

Añade un nuevo campo o restablece el valor de un campo existente.

Si la expresión se evalúa como $$REMOVE, el campo se excluye en la salida. Para obtener más información, consulta Excluye campos de forma condicional.

<field>: <0 or false>

Especifica la exclusión de un campo.

Para excluir un campo de forma condicional, utiliza la variable REMOVE en su lugar. Para obtener más información, consulta Excluye campos de forma condicional.

Si especificas la exclusión de un campo distinto de _id, no podrás utilizar ninguna otra forma de especificación $project. Esta restricción no se aplica a la exclusión condicional de un campo mediante la variable REMOVE.

Consultar también la $unset etapa para excluir campos.

  • El campo _id se incluye, por defecto, en los documentos de salida. Para incluir cualquier otro campo de los documentos de entrada en los documentos de salida, debe especificar explícitamente la inclusión en $project.

  • Si especificas la inclusión de un campo que no existe en el documento, $project ignora esa inclusión y no añade el campo al documento.

Por defecto, el campo _id se incluye en los documentos de salida. Para excluir el campo _id de los documentos de salida, debe especificarse explícitamente la supresión del campo _id en $project.

Si se especifica la exclusión de un campo o varios campos, todos los demás campos se devuelven en los documentos de salida.

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

Si especificas la exclusión de un campo distinto de _id, no puedes emplear ninguna otra forma de especificación $project: es decir, si excluyes campos, no puedes especificar la inclusión de campos, restablecer el valor de campos existentes o agregar campos nuevos. Esta restricción no se aplica a la exclusión condicional de un campo usando la variable REMOVE.

Consultar también la $unset etapa para excluir campos.

Puedes usar la variable REMOVE en expresiones de agregación para suprimir condicionalmente un campo. Para un ejemplo, ve Excluir campos condicionalmente.

Nota

MongoDB también proporciona $addFields para añadir nuevos campos a los documentos.

Para agregar un nuevo campo o restablecer el valor de un campo existente, especifique el nombre del campo y establezca su valor en alguna expresión. Para obtener más información sobre las expresiones, consulte Expresiones.

Para establecer el valor de un campo directamente en un literal numérico o booleano, en lugar de establecer el campo en una expresión que se resuelva en un literal, utilizar el operador $literal. De lo contrario, $project trata el literal numérico o booleano como un indicador para incluir o excluir el campo.

Al especificar un nuevo campo y establecer el valor en la ruta de campo de un campo existente, se puede renombrar un campo de manera efectiva.

La etapa $project admite el uso de los corchetes [] para crear directamente nuevos campos de arreglo. Si especificas campos de arreglo que no existen en un documento, la operación sustituye null como valor de ese campo. Para ver un ejemplo, consulta Proyecto nuevos campos de arreglo.

No puedes utilizar un índice de arreglo con la etapa $project. Para obtener más información, consulta Los índices de arreglos no son compatibles.

Al proyectar o añadir/restablecer un campo dentro de un documento incrustado, puede utilizar notación de puntos, como en

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

O puede anidar los campos:

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

Al anidar los campos, no puedes utilizar la notación de puntos dentro del documento incrustado para especificar el campo, por ejemplo, contact: { "address.country": <1 or 0 or expression> } es inválido.

No puede especificar tanto un documento incrustado como un campo dentro de ese documento incrustado en la misma proyección.

La siguiente etapa $project falla con un error Path collision porque intenta proyectar tanto el documento incrustado contact como el campo contact.address.country:

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

El error ocurre independientemente del orden en que se especifiquen el documento principal y el campo incrustado. El siguiente $project falla con el mismo error:

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

Cuando se usa una etapa $project, normalmente debería ser la última etapa del pipeline, utilizada para especificar qué campos devolver al cliente.

Usar una etapa $project al principio o en la mitad de una pipeline para reducir la cantidad de campos pasados a las siguientes etapas de la pipeline probablemente no mejorará el rendimiento, ya que la base de datos realiza automáticamente esta optimización.

MongoDB devuelve un error si a la etapa $project se le pasa un documento vacío.

Por ejemplo, ejecutar la siguiente pipeline produce un error:

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

No puedes utilizar un índice de arreglo con la etapa $project. Para obtener más información, consulta Los índices de arreglos no son compatibles.

Considere una colección books con el siguiente documento:

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

La siguiente $project etapa incluye solo los campos _id, title y el author en sus documentos de salida:

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

La operación produce el siguiente documento:

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

El campo _id siempre se incluye por defecto. Para excluir el campo _id de los documentos de salida de la etapa $project, especifique la exclusión del campo _id configurándolo en 0 en el documento de proyección.

Considere una colección books con el siguiente documento:

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

La siguiente $project etapa excluye el campo _id pero incluye los campos title y author en sus documentos de salida:

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

La operación produce el siguiente documento:

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

Considere una colección books con el siguiente documento:

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

La siguiente $project etapa excluye el campo lastModified de la salida:

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

Consultar también la $unset etapa para excluir campos.

Considere una colección books con el siguiente documento:

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

La siguiente etapa $project excluye los campos author.first y lastModified de la salida:

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

Alternativamente, se puede anidar la especificación de exclusión en un documento:

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

Ambas especificaciones producen el mismo resultado:

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

Consultar también la $unset etapa para excluir campos.

Puedes usar la variable REMOVE en expresiones de agregación para suprimir condicionalmente un campo.

Considere una colección books con el siguiente 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"
}

La siguiente $project etapa utiliza la variable REMOVE para excluir el campo author.middle solo si es 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"
}
}
}
}
] )

La operación de agregación da el siguiente resultado:

{ "_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" } }

Tip

Comparación con $addFields

Puedes usar la plataforma $addFields o $project para remover campos de documentos. El mejor enfoque depende de su pipeline y de cuánto del documento original desea conservar.

Para ver un ejemplo de uso de $$REMOVE en una etapa $addFields, consulte Remover campos.

Considera una colección bookmarks con los siguientes 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 solo el campo title en el documento incrustado en el campo stop, puede utilizarse la notación de puntos:

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

O puede anidar la especificación de inclusión en un documento:

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

Ambas especificaciones resultan en los siguientes documentos:

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

Considere una colección books con el siguiente documento:

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

La siguiente $project etapa agrega los nuevos campos isbn, lastName y 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"
}
}
]
)

La operación produce el siguiente documento:

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

Por ejemplo, si una colección incluye el siguiente documento:

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

La siguiente operación proyecta los campos x y y como elementos en un nuevo campo myArray:

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

La operación devuelve el siguiente documento:

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

Si la especificación de la matriz incluye campos que no existen en un documento, la operación sustituye null como valor para ese campo.

Por ejemplo, dado el mismo documento que antes, la siguiente operación proyecta los campos x, y y un campo inexistente $someField como elementos en un nuevo campo myArray:

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

La operación devuelve el siguiente documento:

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

No puede utilizar un índice de arreglo con la etapa $project. Esta sección muestra un ejemplo.

Cree la siguiente colección pizzas:

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

El siguiente ejemplo devuelve la pizza:

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

La pizza se devuelve en el resultado del ejemplo:

[ { x: [ 'Pepperoni' ] } ]

El siguiente ejemplo utiliza un índice de arreglo ($name.0) para intentar devolver la pizza:

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

La pizza no se incluye en la salida del ejemplo:

[ { x: [] } ]

Volver

$planCacheStats

En esta página