Definición
$outToma los documentos devueltos por la canalización de agregación y los guarda en una colección especificada. Puede especificar la base de datos de salida.
La etapa
$outdebe ser la última etapa del pipeline. El operador$outpermite que el marco de agregación devuelva conjuntos de resultados de cualquier tamaño.Advertencia
Si la colección especificada por la operación
$outya existe, entonces la etapa$outreemplaza de forma atómica la colección existente con la nueva colección de resultados al completar la agregación. Ver Reemplazar colección existente para más detalles.
Sintaxis
La etapa $out tiene la siguiente sintaxis:
$outpuede tomar un string para especificar solo la colección de salida (es decir, salida a una colección en la misma base de datos):{ $out: "<output-collection>" } // Output collection is in the same database $outpuede utilizar un documento para especificar la base de datos de salida, así como la colección de salida:{ $out: { db: "<output-db>", coll: "<output-collection>" } } A partir de MongoDB 7.0.3 y 7.1,
$outpuede tomar un documento para emitir a un colección de series de tiempo:{ $out: { db: "<output-db>", coll: "<output-collection>", timeseries: { timeField: "<field-name>", metaField: "<field-name>", granularity: "seconds" || "minutes" || "hours" , } } } Importante
Cambio de la granularidad de las series de tiempo
Después de crear una colección de series de tiempo, se puede modificar la granularidad utilizando el método
collMod. Sin embargo, solo se puede aumentar el intervalo de tiempo cubierto por cada bucket. No se puede disminuir.CampoDescripcióndbEl nombre de la base de datos de salida.
Para un Set de réplicas o un autónomo, si la base de datos de salida no existe,
$outtambién crea la base de datos.Para un clúster particionado, la base de datos de salida especificada ya debe existir.
collEl nombre de la colección de salida.
timeseriesUn documento que especifica la configuración a utilizar al escribir en una colección de series de tiempo. El
timeFieldes necesario. Todos los demás campos son opcionales.timeFieldRequerido al escribir en una colección de series de tiempo. El nombre del campo que contiene la fecha en cada documento de serie de tiempo. Los documentos en una colección de series de tiempo deben tener una fecha BSON válida como valor para el
timeField.metaFieldOpcional. El nombre del campo que contiene los metadatos en cada documento de serie de tiempo. Los metadatos del campo especificado deben ser datos que se utilicen para etiquetar una serie única de documentos. Los metadatos difícilmente cambien. El nombre del campo especificado no puede ser
_idni el mismo que eltimeseries.timeField. El campo puede ser de cualquier tipo de dato.Aunque el campo
metaFieldes opcional, el uso de metadatos puede mejorar la optimización de query. Por ejemplo, MongoDB crea un índice compuesto automáticamente en los camposmetaFieldytimeFieldpara las nuevas colecciones. Si no proporcionas un valor para este campo, los datos se agrupan únicamente en función del tiempo.granularityOpcional. No utilice si se configuran
bucketRoundingSecondsybucketMaxSpanSeconds.Los valores posibles son
seconds(por defecto),minutesyhours.Configure
granularityal valor que más se asemeje al intervalo de tiempo entre las marcas de tiempo entrantes consecutivas. Esto mejora el rendimiento al optimizar cómo MongoDB almacena los datos en la colección.Para obtener más información sobre la granularidad y los intervalos de agrupación, consulta Configurar granularidad para datos de series de tiempo.
bucketMaxSpanSecondsOpcional. Utilice con
bucketRoundingSecondscomo alternativa agranularity. Establece el tiempo máximo entre marcas de tiempo en el mismo bucket.Los valores posibles son de 1 a 31536000.
Nuevo en la versión 6.3.
bucketRoundingSecondsOpcional. Utilice con
bucketMaxSpanSecondscomo alternativa agranularity. Debe ser igual abucketMaxSpanSeconds.Cuando un documento requiere un nuevo bucket, MongoDB redondea hacia abajo el valor de la marca de tiempo del documento según este intervalo para establecer el tiempo mínimo para el bucket.
Nuevo en la versión 6.3.
Importante
No puede especificar una colección fragmentada como la colección de salida. La colección de entrada para un pipeline se puede fragmentar. Para exportar a una colección fragmentada, consulta
$merge.El operador
$outno puede guardar resultados en una colección con tamaño fijo.Si modificas una colección con un índice de Búsqueda Atlas, debes borrar primero y luego volver a crear el índice de búsqueda. Considera usar
$mergeen su lugar.
Comparación con $merge
MongoDB ofrece dos etapas, $merge y $out, para escribir los resultados del pipeline de agregación en una colección. A continuación, se resumen las capacidades de las dos etapas:
$out | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
|
Comportamientos
Ejecutar operaciones de lectura $out en nodos secundarios del set de réplicas
A partir de MongoDB 5.0, $out puede ejecutarse en nodos secundarios de un set de réplicas si todos los nodos del clúster tienen featureCompatibilityVersion configurado como 5.0 o superior y la preferencia de lectura configurada como secundaria.
Las operaciones de lectura de la instrucción $out ocurren en los nodos secundarios, mientras que las operaciones de guardado ocurren solo en los nodos primarios.
No todas las versiones del driver son compatibles con la dirección de las operaciones $out a los nodos secundarios del set de réplicas. Se debe consultar la documentación del driver para ver cuándo el driver agregó soporte para $out ejecutado en un nodo secundario.
Crear nueva colección
La operación $out crea una nueva colección si aún no existe.
La colección aparece cuando se completa la agregación. Si la agregación falla, MongoDB no crea la colección.
Sustituir la colección existente
Si la colección de salida ya existe, la etapa $out la reemplaza de forma atómica al completar la agregación. Específicamente, la operación $out:
Crea una colección temporal.
Copia los índices de la colección existente a la colección temporal.
Inserta los documentos en la colección temporal.
Llama al comando
renameCollectioncondropTarget: truepara renombrar la colección temporal a la colección de destino.
Si la colección especificada existe y la operación $out especifica las opciones timeseries, se aplican las siguientes restricciones:
La colección existente debe ser una colección de series de tiempo.
La colección existente no debe ser una vista.
Las opciones
timeseriesincluidas en la etapa$outdeben coincidir exactamente con las de la colección existente.
La operación $out no modifica ningún índice que existiera en la colección anterior. Si la agregación falla, la operación $out no realiza cambios en la colección preexistente.
Errores de validación de esquema
Si su colección coll utiliza la validación de esquemas y tiene validationAction establecido en error, al insertar un documento no válido con $out se arroja un error. La operación $out no realiza cambios en la colección preexistente y los documentos devueltos por la canalización de agregación no se añaden a la colección coll.
Restricciones de índices
El pipeline no se completará si los documentos producidos por el mismo violan algunos índices únicos, incluido el índice en el campo _id de la colección de salida original.
Si la operación $out modifica una colección con un índice de Atlas Search, debes eliminar y volver a crear el índice de búsqueda. Considera usar $merge en su lugar.
majority readConcern
Puede especificar el nivel de consistencia de lectura "majority" para una agregación que incluya una etapa $out.
Interacción con mongodump
Un mongodump iniciado con --oplog falla si un cliente emite un pipeline de agregación que incluye $out durante el proceso de vaciado. Consulta mongodump --oplog para obtener más información.
Restricciones
Restricciones | Descripción |
|---|---|
La pipeline de agregación no puede usar | |
En versiones de MongoDB anteriores a 7.0.3, una pipeline de agregación no puede usar | |
| No puedes incluir la etapa |
| El pipeline anidado de la etapa |
| El pipeline anidado de la etapa |
| La etapa |
Ejemplos
Los ejemplos de esta página utilizan datos del conjunto de datos de muestra sample_mflix. Para obtener más información sobre cómo cargar este conjunto de datos en la implementación autogestionada de MongoDB, consultar Cargar el conjunto de datos de muestra. Si se realizó alguna modificación en las bases de datos de muestra, es posible que se deban descartar y volver a crear las bases de datos para ejecutar los ejemplos de esta página.
Salida a la misma base de datos
La siguiente operación de agregación filtra las películas con una duración superior a 1000 minutos, las agrupa por año de lanzamiento y recopila su título en un arreglo. El pipeline guarda los resultados en la colección movies_by_year de la base de datos sample_mflix.
db.movies.aggregate( [ { $match : { runtime : { $gt : 1000 } } }, { $group : { _id : "$year", movies: { $push: "$title" } } }, { $out : "movies_by_year" } ] )
- Primera etapa (
$match): - La etapa
$matchfiltra las películas con unruntimemayor que1000. - Segunda etapa (
$group): - La etapa de
$groupagrupa por el campoyeary utiliza$pushpara añadir los títulos a un campo de arreglomovies. - Tercera etapa (
$out): - La etapa
$outenvía los documentos a la colecciónmovies_by_yearen la base de datossample_mflix.
Para ver los documentos en la colección de salida, ejecute la siguiente operación:
db.movies_by_year.find().sort( { _id: 1 } )
[ { _id: 1978, movies: [ 'Centennial' ] }, { _id: 1994, movies: [ 'Baseball' ] } ]
Salida a una base de datos diferente
Nota
Para un Set de réplicas o un autónomo, si la base de datos de salida no existe, $out también crea la base de datos.
Para un clúster particionado, la base de datos de salida especificada ya debe existir.
$out puede generar salida a una colección en una base de datos diferente de donde se ejecuta la agregación.
La siguiente operación de agregación filtra las películas con una duración superior a 1000 minutos, las agrupa por año de lanzamiento y recopila su título en un arreglo. El pipeline guarda los resultados en la colección movies_by_year de la base de datos reporting:
db.movies.aggregate( [ { $match : { runtime : { $gt : 1000 } } }, { $group : { _id : "$year", movies: { $push: "$title" } } }, { $out : { db: "reporting", coll: "movies_by_year" } } ] )
- Primera etapa (
$match): - La etapa
$matchfiltra las películas con unruntimemayor que1000. - Segunda etapa (
$group): - La etapa de
$groupagrupa por el campoyeary utiliza$pushpara añadir los títulos a un campo de arreglomovies. - Tercera etapa (
$out): - La etapa
$outenvía los documentos a la colecciónmovies_by_yearen la base de datosreporting.
Para ver los documentos en la colección de salida, ejecute la siguiente operación:
db.movies_by_year.find().sort( { _id: 1 } )
[ { _id: 1978, movies: [ 'Centennial' ] }, { _id: 1994, movies: [ 'Baseball' ] } ]
Los ejemplos de C# en esta página utilizan la base de datos sample_mflix de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulta Primeros pasos en la documentación del controlador de MongoDB .NET/C#.
La siguiente clase Movie modela los documentos en la colección sample_mflix.movies:
[] public class Movie { [] public ObjectId Id { get; set; } [] public string Title { get; set; } = null!; [] public int? Year { get; set; } [] public int? Runtime { get; set; } [] public string? Rated { get; set; } [] public int Metacritic { get; set; } [] public string? Plot { get; set; } [] public string? Type { get; set; } [] public string[]? Cast { get; set; } [] public string[]? Directors { get; set; } [] public string[]? Writers { get; set; } [] public ImdbData? Imdb { get; set; } }
Para usar el controlador de MongoDB .NET/C# para añadir una etapa $out a un pipeline de agregación, llama al Out() método en un objeto PipelineDefinition.
El siguiente ejemplo crea una etapa de la pipeline que busca películas donde el valor del campo metacritic sea 100, las ordena por título y escribe los resultados en la colección top_movies:
var outCollection = _client .GetDatabase("sample_mflix") .GetCollection<Movie>("top_movies"); var pipeline = new EmptyPipelineDefinition<Movie>() .Match(Builders<Movie>.Filter.Eq(m => m.Metacritic, 100)) .Sort(Builders<Movie>.Sort.Ascending(m => m.Title)) .Out(outCollection);
{"_id": "...", "title": "Best Kept Secret", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "Boyhood", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "Fanny and Alexander", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "Lawrence of Arabia", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "The Conformist", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "The Godfather", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "The Leopard", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "The Wizard of Oz", "runtime": "...", "metacritic": 100, "imdb": "..."}
Los ejemplos de Node.js en esta página utilizan la base de datos sample_mflix de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulte Primeros pasos en la documentación del controlador de MongoDB Node.js.
Para utilizar el controlador de MongoDB Node.js para agregar una etapa de $out a una canalización de agregación, utilice el Operador $out en un objeto de canalización.
El siguiente ejemplo crea una etapa del pipeline que escribe los resultados del pipeline en la colección movies. A continuación, el ejemplo ejecuta el pipeline de agregación:
const pipeline = [{ $out: { db: "sample_mflix", coll: "movies" } }]; const cursor = collection.aggregate(pipeline); return cursor;