db.collection.insertMany()
MongoDB com drivers
Esta página documenta um método mongosh
. Para ver o método equivalente em um driver MongoDB, consulte a página correspondente da sua linguagem de programação:
Definição
db.collection.insertMany()
Insere vários documentos em uma coleção.
Retorna: Um documento contendo:
Um
acknowledged
booleano, definido comotrue
se a operação correu com preocupação de gravação oufalse
se o preocupação de gravação foi desativadoUm
insertedIds
array, contendo_id
valores para cada documento inserido com sucesso
Compatibilidade
Você pode utilizar o db.collection.insertMany()
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
Sintaxe
O método insertMany()
tem a seguinte sintaxe:
db.collection.insertMany( [ <document 1> , <document 2>, ... ], { writeConcern: <document>, ordered: <boolean> } )
Parâmetro | Tipo | Descrição |
---|---|---|
document | documento | Uma array de documentos para inserir na collection. |
writeConcern | documento | Opcional. Um documento que expressa o write concern. Omitir para usar o write concern padrão. Não defina explicitamente a preocupação de gravação para a operação se for executada em uma transação. Para usar write concern com transações, consulte Transações e write concern. |
ordered | booleano | Opcional. Um booleano que especifica se a instância do mongod deve executar uma inserção ordenada ou não ordenada. O padrão é true . |
Comportamentos
Dado um array de documentos, insertMany()
insere cada documento do array na coleção.
Execução de operações
Por padrão, os documentos são inseridos em ordem.
Se ordered
estiver definido como falso, os documentos serão inseridos em um formato não ordenado e poderão ser reordenados por mongod
para aumentar o desempenho. Os aplicativos não devem depender da ordem de inserções se usarem um insertMany()
não ordenado.
O número de operações em cada grupo não pode exceder o valor do maxWriteBatchSize do banco de dados. A partir do MongoDB 3,6, esse valor é 100,000
. Este valor é mostrado no campo hello.maxWriteBatchSize
.
Esse limite evita problemas com mensagens de erro superdimensionadas. Se um grupo exceder este limite, o driver do cliente dividirá o grupo em grupos menores com contagens menores ou iguais ao valor do limite. Por exemplo, com o valor de maxWriteBatchSize
de 100,000
, se a fila for composta por 200,000
operações, o driver criará 2 grupos, cada um com 100,000
operações.
Observação
O driver só divide o grupo em grupos menores ao usar a API de alto nível. Se estiver usando db.runCommand() diretamente (por exemplo, ao gravar um driver), o MongoDB lançará um erro ao tentar executar um lote de gravação que exceda o limite.
A partir do MongoDB 3.6, uma vez que o relatório de erros de um único lote fica muito grande, o MongoDB trunca todas as mensagens de erro restantes em uma string vazia. Atualmente, começa quando há pelo menos 2 mensagens de erro com tamanho total maior que 1MB
.
Os tamanhos e mecânicas de agrupamento são detalhes de desempenho interno e estão sujeitos a alterações em versões futuras.
A execução de uma lista de operações ordered
em uma collection fragmentada geralmente será mais lenta do que a execução de uma lista unordered
, já que, com uma lista ordenada, cada operação deve aguardar a conclusão da operação anterior.
Criação de collections
Se a coleção não existir, insertMany()
criará a coleção quando a gravação for bem-sucedida.
_id
Campo
Se o documento não especificar um campo _id, então mongod
adicionará o campo _id
e atribuirá um ObjectId()
exclusivo para o documento. A maioria dos drivers cria um ObjectId e insere o campo _id
, mas o mongod
criará e preencherá o _id
se o driver ou o aplicativo não o fizer.
Se o documento contiver um campo _id
, o valor _id
deverá ser único dentro da collection para evitar erro de chave duplicada.
Explicabilidade
insertMany()
não é compatível com db.collection.explain()
.
Error Handling
As inserções geram uma exceção BulkWriteError
.
Excluindo os erros de preocupação de gravação, as operações ordenadas são interrompidas após um erro, enquanto as operações não ordenadas continuam a processar todas as operações de gravação restantes na fila.
Os erros de write concern são exibidos no campo writeConcernErrors
, enquanto todos os outros erros são exibidos no campo writeErrors
. Se um erro for encontrado, o número de operações de gravação bem-sucedidas será exibido em vez de uma lista de _ids inseridos. Operações ordenadas exibem o único erro encontrado enquanto operações não ordenadas exibem cada erro em uma array.
Erros de validação de esquema
Se sua coleção usa validação de esquema e tem validationAction
definido como error
, inserir um documento inválido com db.collection.insertMany()
gera um writeError
. Os documentos que precedem o documento inválido na matriz documents
são gravados na coleção. O valor do campo ordered
determina se os documentos válidos restantes serão inseridos.
Transações
db.collection.insertMany()
pode ser usado dentro de transações distribuídas.
Importante
Na maioria dos casos, uma transação distribuída incorre em um custo de desempenho maior do que as gravações de um único documento, e a disponibilidade de transações distribuídas não deve substituir o design eficaz do esquema. Em muitos cenários, o modelo de dados desnormalizado (documentos e arrays incorporados) continuará a ser ideal para seus dados e casos de uso. Ou seja, para muitos cenários, modelar seus dados adequadamente minimizará a necessidade de transações distribuídas.
Para considerações adicionais sobre o uso de transações (como limite de tempo de execução e limite de tamanho do oplog), consulte também Considerações de produção.
Criação de collections em transações
Você pode criar coleção e indexes dentro de uma transaction distribuída se a transaction não for uma transação de escrita de estilhaço cruzado.
Se você especificar uma inserção em uma collection não existente em uma transação, o MongoDB criará a collection implicitamente.
Write concerns e transações
Não defina explicitamente a preocupação de gravação para a operação se for executada em uma transação. Para usar write concern com transações, consulte Transações e write concern.
Consideração de desempenho para dados aleatórios
Se uma operação insere uma grande quantidade de dados aleatórios (por exemplo, índices com hash) em um campo indexado, o desempenho da inserção pode diminuir. Inserções em massa de dados aleatórios criam entradas de índice aleatórias, o que aumenta o tamanho do índice. Se o índice atingir o tamanho que requer cada inserção aleatória para acessar uma entrada de índice diferente, as inserções resultarão em uma alta taxa de remoção e substituição do cache WiredTiger. Quando isso acontece, o índice não está mais totalmente no cache e é atualizado no disco, o que diminui o desempenho.
Para melhorar o desempenho de inserções em massa de dados aleatórios em campos indexados, você pode:
Soltar o índice e recriá-o depois de inserir os dados aleatórios.
Insira os dados em uma coleção não indexada vazia.
A criação do índice após a inserção em massa classifica os dados na memória e executa uma inserção ordenada em todos os índices.
Entradas de oplog
Se uma operação db.collection.insertMany()
inserir com êxito um ou mais documentos, a operação adicionará uma entrada no oplog (log de operações) para cada documento inserido. Se a operação falhar, ela não adicionará uma entrada no oplog.
Exemplos
Os exemplos a seguir inserem documentos na coleção products
.
Inserir Vários documentos sem especificar um _id
campo
O exemplo a seguir usa db.collection.insertMany()
para inserir documentos que não contêm o campo _id
:
try { db.products.insertMany( [ { item: "card", qty: 15 }, { item: "envelope", qty: 20 }, { item: "stamps" , qty: 30 } ] ); } catch (e) { print (e); }
A operação retorna o seguinte documento:
{ "acknowledged" : true, "insertedIds" : [ ObjectId("562a94d381cb9f1cd6eb0e1a"), ObjectId("562a94d381cb9f1cd6eb0e1b"), ObjectId("562a94d381cb9f1cd6eb0e1c") ] }
Como os documentos não incluíam _id
, mongod
cria e adiciona o campo _id
para cada documento e atribui a ele um valor deObjectId()
exclusivo.
Os valores ObjectId
são específicos da máquina e do momento em que a operação é executada. Dessa forma, seus valores podem ser diferentes dos do exemplo.
Inserir vários documentos especificando um _id
campo
O exemplo/operação a seguir utiliza insertMany()
para inserir documentos que incluem o campo _id
. O valor de _id
deve ser exclusivo dentro da coleção para evitar um erro de chave duplicada.
try { db.products.insertMany( [ { _id: 10, item: "large box", qty: 20 }, { _id: 11, item: "small box", qty: 55 }, { _id: 12, item: "medium box", qty: 30 } ] ); } catch (e) { print (e); }
A operação retorna o seguinte documento:
{ "acknowledged" : true, "insertedIds" : [ 10, 11, 12 ] }
A inserção de um valor duplicado para qualquer chave que faça parte de um índice único, como _id
, gera uma exceção. A opção a seguir tenta inserir um documento com um valor _id
que já existe:
try { db.products.insertMany( [ { _id: 13, item: "envelopes", qty: 60 }, { _id: 13, item: "stamps", qty: 110 }, { _id: 14, item: "packing tape", qty: 38 } ] ); } catch (e) { print (e); }
Como _id: 13
já existe, a seguinte exceção é gerada:
BulkWriteError({ "writeErrors" : [ { "index" : 0, "code" : 11000, "errmsg" : "E11000 duplicate key error collection: inventory.products index: _id_ dup key: { : 13.0 }", "op" : { "_id" : 13, "item" : "stamps", "qty" : 110 } } ], "writeConcernErrors" : [ ], "nInserted" : 1, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] })
Observe que um documento foi inserido: O primeiro documento de _id: 13
será inserido com sucesso, mas a segunda inserção falhará. Isso também impedirá que documentos adicionais deixados na fila sejam inseridos.
Com ordered
a false
, a operação de inserção continuaria com quaisquer documentos restantes.
Inserções não ordenadas
As seguintes tentativas para inserir múltiplos documentos com o campo _id
e ordered: false
. O array de documentos contém dois documentos com campos _id
duplicados.
try { db.products.insertMany( [ { _id: 10, item: "large box", qty: 20 }, { _id: 11, item: "small box", qty: 55 }, { _id: 11, item: "medium box", qty: 30 }, { _id: 12, item: "envelope", qty: 100}, { _id: 13, item: "stamps", qty: 125 }, { _id: 13, item: "tape", qty: 20}, { _id: 14, item: "bubble wrap", qty: 30} ], { ordered: false } ); } catch (e) { print (e); }
A operação apresenta a seguinte exceção:
BulkWriteError({ "writeErrors" : [ { "index" : 2, "code" : 11000, "errmsg" : "E11000 duplicate key error collection: inventory.products index: _id_ dup key: { : 11.0 }", "op" : { "_id" : 11, "item" : "medium box", "qty" : 30 } }, { "index" : 5, "code" : 11000, "errmsg" : "E11000 duplicate key error collection: inventory.products index: _id_ dup key: { : 13.0 }", "op" : { "_id" : 13, "item" : "tape", "qty" : 20 } } ], "writeConcernErrors" : [ ], "nInserted" : 5, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] })
Embora o documento com item: "medium box"
e item: "tape"
tenha falhado ao ser inserido devido a valores duplicados _id
, nInserted
mostra que os 5 documentos restantes foram inseridos.
Usando write concern
Dado um conjunto de réplicas de três membros, a operação a seguir especifica um w
de majority
e wtimeout
de 100
try { db.products.insertMany( [ { _id: 10, item: "large box", qty: 20 }, { _id: 11, item: "small box", qty: 55 }, { _id: 12, item: "medium box", qty: 30 } ], { w: "majority", wtimeout: 100 } ); } catch (e) { print (e); }
Se o primário e pelo menos um secundário reconhecerem cada operação de gravação dentro de 100 milissegundos, ele retornará:
{ "acknowledged" : true, "insertedIds" : [ ObjectId("562a94d381cb9f1cd6eb0e1a"), ObjectId("562a94d381cb9f1cd6eb0e1b"), ObjectId("562a94d381cb9f1cd6eb0e1c") ] }
Se o tempo total necessário para que todos os nós necessários no conjunto de réplicas reconheçam a operação de gravação for maior que wtimeout
, a writeConcernError
a seguir será exibida quando o período de wtimeout
tiver passado.
Esta operação retorna:
WriteConcernError({ "code" : 64, "errmsg" : "waiting for replication timed out", "errInfo" : { "wtimeout" : true, "writeConcern" : { "w" : "majority", "wtimeout" : 100, "provenance" : "getLastErrorDefaults" } } })