$out (agregação)
Nesta página
Definição
$out
Pega os documentos retornados pelo pipeline de agregação e os grava na coleção especificada. Você pode especificar o banco de dados de saída.
O estágio
$out
deve ser o último estágio do pipeline. O operador$out
permite que o framework de aggregation retorne conjuntos de resultados de qualquer tamanho.Aviso
Se a coleção especificada pela operação
$out
já existir, então a etapa$out
substituirá atomicamente a coleção existente pela nova coleção de resultados após a conclusão da agregação. Consulte Substituir coleção existente para mais informações.
Sintaxe
O estágio $out
tem a seguinte sintaxe:
$out
pode usar uma string para especificar somente a collection de saída (ou seja, saída para uma collection no mesmo banco de dados):{ $out: "<output-collection>" } // Output collection is in the same database $out
pode usar um documento para especificar o banco de dados de saída, bem como a coleção de saída:{ $out: { db: "<output-db>", coll: "<output-collection>" } } A partir do MongoDB 7.0.3 e 7.1,
$out
pode levar um documento para a saída para uma coleção de séries temporais:{ $out: { db: "<output-db>", coll: "<output-collection>", timeseries: { timeField: "<field-name>", metaField: "<field-name>", granularity: "seconds" || "minutes" || "hours" , } } } Importante
Alterando a granularidade de série temporal
Depois de criar uma coleção de séries temporais, você poderá modificar sua granularidade usando o método
collMod
. No entanto, você só pode aumentar o intervalo de tempo coberto por cada bucket. Você não pode diminuí-lo.CampoDescriçãodb
O nome do banco de dados de saída.
Para um conjunto de réplicas ou um standalone, se o banco de dados de saída não existir,
$out
também criará o banco de dados.Para um cluster fragmentado, o banco de dados de saída especificado já deve existir.
coll
O nome da collection de saída.
timeseries
Um documento que especifica a configuração a ser usada ao gravar em uma coleção de séries temporais. O
timeField
é obrigatório. Todos os outros campos são opcionais.timeField
Obrigatório ao gravar em uma coleção de séries temporais. .. include:: /includes/time-series/fact-time-field-description.rst
metaField
Opcional. O nome do campo que contém metadados em cada documento de série temporal. Os metadados no campo especificado devem ser dados utilizados para rotular uma série exclusiva de documentos. Os metadados raramente devem mudar. O nome do campo especificado não pode ser
_id
ou o mesmo que otimeseries.timeField
. O campo pode ser de qualquer tipo de dados.Embora o campo
metaField
seja opcional, o uso de metadados pode melhorar a otimização da query. Por exemplo, o MongoDB cria automaticamente um índice composto nos camposmetaField
etimeField
para novas collections. Se você não fornecer um valor para este campo, os dados serão agrupados exclusivamente com base no tempo.granularity
Opcional. Não use se estiver configurando
bucketRoundingSeconds
ebucketMaxSpanSeconds
.Os valores possíveis são
seconds
(padrão),minutes
ehours
.Defina
granularity
como o valor que mais se aproxima do tempo entre carimbos de data/hora consecutivos de entrada. Isso melhora o desempenho otimizando a forma como o MongoDB armazena dados na collection.Para obter mais informações sobre granularidade e intervalos de bucket, consulte Definir granularidade para dados de séries temporais.
bucketMaxSpanSeconds
Opcional. Use com
bucketRoundingSeconds
como alternativa agranularity
. Define o tempo máximo entre os carimbos de data/hora no mesmo bloco.Os valores possíveis são 1-31536000.
Novidades na versão 6.3.
bucketRoundingSeconds
Opcional. Use com
bucketMaxSpanSeconds
como alternativa agranularity
. Deve ser igual abucketMaxSpanSeconds
.Quando um documento requer um novo bucket, o MongoDB arredonda para baixo o valor de carimbo de data/hora do documento por esse intervalo para definir o tempo mínimo para o bucket.
Novidades na versão 6.3.
Importante
Você não pode especificar uma collection fragmentada como collection de saída. A collection de entrada de um pipeline pode ser fragmentada. Para gerar uma saída para uma collection fragmentada, consulte
$merge
.O operador
$out
não pode gravar resultados em uma capped collection.Se você modificar uma coleção com um índice do Atlas Search, deverá primeiro excluir e depois recriar o índice de pesquisa. Então considere usar
$merge
.
Comparação com $merge
O MongoDB fornece dois estágios, $merge
e $out
, para escrever os resultados do aggregation pipeline em uma collection. A seguir, resumimos as capacidades dos dois estágios:
$out | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
|
Comportamentos
Operações de leitura $out são executadas em membros secundários do conjunto de réplicas
A partir do MongoDB 5.0, $out
pode ser executado em nós secundários do conjunto de réplicas se todos os nós no cluster tiverem featureCompatibilityVersion definido como 5.0
ou superior e a read preference estiver definida como secundária.
As operações de leitura da instrução $out
ocorrem nos nós secundários, enquanto as operações de gravação ocorrem somente nos nós primários.
Nem todas as versões de driver aceitam o direcionamento de operações $out
para nós secundários de conjuntos de réplicas. Verifique a documentação do driver para ver quando ele passou a oferecer suporte a $out
em execução em um secundário.
Criar nova collection
A operação $out
cria uma nova collection se ainda não houver uma.
A collection não fica visível até que a aggregation seja concluída. Se ela falhar, o MongoDB não criará a collection.
Substituir collection existente
Se a collection especificada pela operação $out
já existir, após a conclusão da aggregation, o estágio $out
substituirá atomicamente a collection existente pela nova collection de resultados. Especificamente, a operação $out
:
Cria uma collection temporária.
Copia os índices da collection existente para a collection temporária.
Insere os documentos na collection temporária.
Chama o comando
renameCollection
comdropTarget: true
para renomear a collection temporária para a collection de destino.
Se existe uma collection especificada e a operação $out
especifica as opções do timeseries
, então as seguintes restrições se aplicam:
A collection existente deve ser uma coleção de séries temporais.
A collection existente não deve ser uma visualização.
As opções de
timeseries
incluídas no estágio$out
devem corresponder exatamente às da collection existente.
A operação $out
não altera nenhum índice existente na collection anterior. Se a aggregation falhar, a operação $out
não fará alterações na collection pré-existente.
Erros de validação de esquema
Se sua coleção coll
usar validação de esquema e tiver validationAction
definido como error
, inserir um documento inválido com $out
gerará um erro. A operação $out
não faz alterações na coleção preexistente, e os documentos retornados pelo pipeline de agregação não são adicionados à coleção coll
.
Restrições de índice
O pipeline não será concluído se os documentos produzidos por ele violarem qualquer índice único, incluindo o índice no campo _id
da collection de saída original.
Se a operação $out
modificar uma coleção com um índice do Atlas Search, você deverá excluir e recriar o índice de pesquisa. Considere usar $merge
.
majority
Preocupação de leitura
Você pode especificar o nível de preocupação de leitura "majority"
de uma agregação que inclui um estágio $out
.
Interação com mongodump
Um mongodump
iniciado com --oplog
falhará se um cliente emitir um pipeline de agregação que contiver $out
durante o processo de despejo. Consulte mongodump --oplog
para obter mais informações.
Restrições
Restrições | Descrição |
---|---|
Um aggregation pipeline não pode usar $out dentro das transações. | |
Nas versões do MongoDB anteriores a 7.0.3, um aggregation pipeline não pode usar $out para gerar uma coleção de séries temporais. | |
$lookup estágio | |
$facet estágio | |
$unionWith estágio | |
"linearizable" Leia a preocupação | O estágio |
Exemplos
No banco de dados do test
, crie uma collection books
com os seguintes documentos:
db.getSiblingDB("test").books.insertMany([ { "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 }, { "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 }, { "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }, { "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 }, { "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 } ])
Se o banco de dados test
ainda não existir, a operação de inserção criará o banco de dados e a collection books
.
Saída para o mesmo banco de dados
A seguinte operação de aggregation reposiciona os dados na collection books
no banco de dados test
para que tenham títulos agrupados por autores e então grava os resultados na collection authors
e no banco de dados test
.
db.getSiblingDB("test").books.aggregate( [ { $group : { _id : "$author", books: { $push: "$title" } } }, { $out : "authors" } ] )
- Primeiro estágio (
$group
): O estágio
$group
se agrupa pelosauthors
e usa$push
para adicionar os títulos a um campo de arraybooks
:{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] } { "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } - Segundo estágio (
$out
): - O estágio
$out
envia os documentos para a collectionauthors
no banco de dadostest
.
Para visualizar os documentos na collection de saída, execute a seguinte operação:
db.getSiblingDB("test").authors.find()
A collection contém os seguintes documentos:
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } { "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
Gerar saídas para um banco de dados diferente
Observação
Para um conjunto de réplicas ou um standalone, se o banco de dados de saída não existir, $out
também criará o banco de dados.
Para um cluster fragmentado, o banco de dados de saída especificado já deve existir.
$out
pode gerar saídas para uma coleção em um banco de dados diferente de onde a agregação é executada.
A operação de aggregation a seguir reposiciona os dados na collection books
para ter títulos agrupados por autores e então grava os resultados na collection authors
no banco de dados reporting
:
db.getSiblingDB("test").books.aggregate( [ { $group : { _id : "$author", books: { $push: "$title" } } }, { $out : { db: "reporting", coll: "authors" } } ] )
- Primeiro estágio (
$group
): O estágio
$group
se agrupa pelosauthors
e usa$push
para adicionar os títulos a um campo de arraybooks
:{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] } { "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } - Segundo estágio (
$out
): - O estágio
$out
envia os documentos para a collectionauthors
no banco de dadosreporting
.
Para visualizar os documentos na collection de saída, execute a seguinte operação:
db.getSiblingDB("reporting").authors.find()
A collection contém os seguintes documentos:
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } { "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }