Obtenha o _id do documento inserido no banco de dados Mongo em NodeJS


100

Eu uso o NodeJS para inserir documentos no MongoDB. Usando collection.insertposso inserir um documento no banco de dados como neste código:

// ...
collection.insert(objectToInsert, function(err){
   if (err) return;
   // Object inserted successfully.
   var objectId; // = ???
});
// ...

Como posso obter o _idobjeto inserido?

Existe alguma maneira de obter o _idobjeto sem inserir o último _id?

Supondo que ao mesmo tempo muitas pessoas acessem o banco de dados, não posso ter certeza se o id mais recente é o id do objeto inserido.

Respostas:


88

Existe um segundo parâmetro para o retorno de chamada para collection.insertque retornará o documento ou documentos inseridos, que devem ter _ids.

Experimentar:

collection.insert(objectToInsert, function(err,docsInserted){
    console.log(docsInserted);
});

e verifique o console para ver o que quero dizer.


4
O retorno de chamada realmente retorna a matriz de documentos inseridos. Portanto, se você inseriu um único documento, poderá acessar o registro inserido conforme abaixo. coleção.insert ({nome: "David", título: "Sobre MongoDB"}, função (err, registros) {console.log ("Registro adicionado como" + registros [0] ._ id);}); Ref: mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
— Rohit Singh Sengar


link não leva a nenhum lugar útil
— davidhadas

Não sei se isso é geral ou só funciona em meteoro, mas quando você chama collection.insert (objeto), ele retorna o id do objeto inserido imediatamente.
— vantesllar

4
docsInserted não retorna um _id para mim. ele retorna para mim {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "selectionId": "7fffffff0000000000000005"}
— user1709076

90

Uma maneira mais curta do que usar o segundo parâmetro para o retorno de chamada de collection.insertseria usar objectToInsert._idque retorna o _id(dentro da função de retorno de chamada, supondo que foi uma operação bem-sucedida).

O driver Mongo para NodeJS anexa o _idcampo à referência do objeto original, portanto, é fácil obter o id inserido usando o objeto original:

collection.insert(objectToInsert, function(err){
   if (err) return;
   // Object inserted successfully.
   var objectId = objectToInsert._id; // this will return the id of object inserted
});

4
Muito perspicaz, obrigado. Não foi possível encontrar essas informações em nenhum outro lugar desde a mudança nos parâmetros de retorno de chamada.
— Brad Hein

@BradHein De nada! Provavelmente, o driver MongoDB modifica a referência do objeto, portanto, ele também é modificado aqui. :)
— Ionică Bizău

Seu código está errado, onde você diz var objectId = objectToInsert._id; você quis dizer var objectId = objectInserted._id;
— Andy Lorenz

3
@AndyLorenz O que é objectInserted? Eu acho que você está perdendo exatamente o ponto desta resposta: o driver Mongo anexa o _idcampo ao objeto original. Editei a resposta para usar em objectToInsertqualquer lugar. Espero que as coisas estejam mais claras agora. :)
— Ionică Bizău

1
NOTA: insert()está obsoleto. Use em insertOne()vez disso
— evilReiko

16

Como disse o ktretyak, para obter o ID do documento inserido, a melhor maneira é usar a propriedade insertId no objeto de resultado. No meu caso, result._id não funcionou, então tive que usar o seguinte:

db.collection("collection-name")
  .insertOne(document)
  .then(result => {
    console.log(result.insertedId);
  })
  .catch(err => {
    // handle error
  });

É a mesma coisa se você usar callbacks.


13

Na verdade, fiz um console.log () para o segundo parâmetro na função de retorno de chamada para inserir. Na verdade, há muitas informações retornadas além do próprio objeto inserido. Portanto, o código abaixo explica como você pode acessar seu id.

collection.insert(objToInsert, function (err, result){
    if(err)console.log(err);
    else {
        console.log(result["ops"][0]["_id"]);
        // The above statement will output the id of the 
        // inserted object
       }
});

Isso resulta em um ObjectID {_bsontype: "ObjectID", id: Buffer(12)}. Como posso usá-lo para obter a id real que está no banco de dados? ... A resposta foi encontrada em outro comentário: Usoresult.insertedId.toString()
— Fadwa

7

O Mongo envia o documento completo como um objeto de retorno de chamada para que você possa simplesmente obtê-lo apenas a partir daí.

por exemplo

collection.save(function(err,room){
  var newRoomId = room._id;
  });

4

Agora você pode usar o método insertOne e no result.insertedId da promessa


Você poderia fornecer um exemplo de código? De onde vem esse objeto de resultado?
— JSideris de

@JSideris, como você pode ver no método de especificação insertOne () , este método aceita três parâmetros (doc, options, callback). O terceiro parâmetro - um retorno de chamada, que leva dois parâmetros (error, result) . E result- é isso que você está procurando.
— ktretyak

2

@JSideris, código de amostra para obter o insertId.

db.collection(COLLECTION).insertOne(data, (err, result) => {
    if (err) 
      return err;
    else 
      return result.insertedId;
  });

2

se você quiser pegar "_id" use simpley

result.insertedId.toString() 

// toString irá converter de hexadecimal


É isso que eu estava procurando. Obrigado.
— Fadwa

Sim, deve ter havido uma mudança de versão, pois as outras respostas não mencionam result.insertedIdé um ObjectIDobjeto de tipo. .toString()irá converter este objeto em um UUID real.
— Dylan Pierce

0

Você pode usar funções assíncronas para obter o campo _id automaticamente sem manipular o objeto de dados:

async function save() {
  const data = {
    name: "John"
  }

  await db.collection('users', data )

  return data
}

Retorna dados:

{
  _id: '5dbff150b407cc129ab571ca',
  name: 'John'
}

0

Outra maneira de fazer isso na função assíncrona:

const express = require('express')
const path = require('path')
const db = require(path.join(__dirname, '../database/config')).db;
const router = express.Router()

// Create.R.U.D
router.post('/new-order', async function (req, res, next) {

    // security check
    if (Object.keys(req.body).length === 0) {
        res.status(404).send({
            msg: "Error",
            code: 404
        });
        return;
    }

    try {

        // operations
        let orderNumber = await db.collection('orders').countDocuments()
        let number = orderNumber + 1
        let order = {
            number: number,
            customer: req.body.customer,
            products: req.body.products,
            totalProducts: req.body.totalProducts,
            totalCost: req.body.totalCost,
            type: req.body.type,
            time: req.body.time,
            date: req.body.date,
            timeStamp: Date.now(),

        }

        if (req.body.direction) {
            order.direction = req.body.direction
        }

        if (req.body.specialRequests) {
            order.specialRequests = req.body.specialRequests
        }

        // Here newOrder will store some informations in result of this process.
        // You can find the inserted id and some informations there too.
        
        let newOrder = await db.collection('orders').insertOne({...order})

        if (newOrder) {

            // MARK: Server response
            res.status(201).send({
                msg: `Order N°${number} created : id[${newOrder.insertedId}]`,
                code: 201
            });

        } else {

            // MARK: Server response
            res.status(404).send({
                msg: `Order N°${number} not created`,
                code: 404
            });

        }

    } catch (e) {
        print(e)
        return
    }

})

// C.Read.U.D


// C.R.Update.D


// C.R.U.Delete



module.exports = router;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.