Obtenga el _id del documento insertado en la base de datos Mongo en NodeJS

100

Utilizo NodeJS para insertar documentos en MongoDB. Usando collection.insertpuedo insertar un documento en la base de datos como en este código:

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

¿Cómo puedo obtener el _idobjeto insertado?

¿Hay alguna forma de obtener el _idúltimo objeto sin insertar _id?

Suponiendo que al mismo tiempo muchas personas acceden a la base de datos, no puedo estar seguro de que la última identificación sea la identificación del objeto insertado.

Ionică Bizău
fuente

Respuestas:

88

Hay un segundo parámetro para la devolución de llamada collection.insertque devolverá el documento o documentos insertados, que deberían tener _ids.

Tratar:

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

y compruebe la consola para ver a qué me refiero.

georgedyer
fuente
4
La devolución de llamada en realidad devuelve una serie de documentos insertados. Entonces, si ha insertado un solo documento, puede acceder al registro insertado como se muestra a continuación. collection.insert ({nombre: "David", título: "Acerca de MongoDB"}, función (err, registros) {console.log ("Registro agregado como" + registros [0] ._ id);}); Ref: mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
Rohit Singh Sengar
2
La API de devoluciones de llamada ha cambiado: mongodb.github.io/node-mongodb-native/2.0/api/…
tenbits
el enlace no lleva a ninguna parte útil
davidhadas
No sé si esto es general o solo funciona en meteoro, pero cuando llama a collection.insert (objeto), devuelve la identificación del objeto insertado de inmediato.
vantesllar
4
docsInserted no devuelve un _id para mí. me devuelve {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "choiceId": "7fffffff0000000000000005"}
user1709076
90

Una forma más corta que usar el segundo parámetro para la devolución de llamada collection.insertsería usar objectToInsert._idque devuelve el _id(dentro de la función de devolución de llamada, suponiendo que fue una operación exitosa).

El controlador Mongo para NodeJS agrega el _idcampo a la referencia del objeto original, por lo que es fácil obtener la identificación insertada utilizando el 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
});
Ionică Bizău
fuente
4
Muy perspicaz gracias. No se pudo encontrar esta información en ningún otro lugar desde el cambio en los parámetros de devolución de llamada.
Brad Hein
@BradHein ¡De nada! Probablemente el controlador MongoDB modifica la referencia del objeto, por lo que también se modifica aquí. :)
Ionică Bizău
Su código es incorrecto, donde dice var objectId = objectToInsert._id; quiso decir var objectId = objectInserted._id;
Andy Lorenz
3
@AndyLorenz ¿Qué es objectInserted? Supongo que se está perdiendo exactamente el punto de esta respuesta: el controlador Mongo agrega el _idcampo al objeto original. Edité la respuesta para usarla en objectToInserttodas partes. Espero que las cosas estén más claras ahora. :)
Ionică Bizău
1
NOTA: insert()está en desuso. Úselo en su insertOne()lugar
evilReiko
16

Como dijo ktretyak, para obtener el ID del documento insertado, la mejor manera es usar la propiedad insertId en el objeto de resultado. En mi caso, result._id no funcionó, así que tuve que usar lo siguiente:

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

Es lo mismo si usa devoluciones de llamada.

Serjuice
fuente
13

De hecho, hice un console.log () para el segundo parámetro en la función de devolución de llamada para insertar. En realidad, se devuelve mucha información además del objeto insertado. Entonces, el código a continuación explica cómo puede acceder a su identificación.

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
       }
});
Sidak
fuente
Esto genera un ObjectID {_bsontype: "ObjectID", id: Buffer(12)}. ¿Cómo puedo usarlo para obtener la identificación real que está en la base de datos? ... Encontré la respuesta en otro comentario: Useresult.insertedId.toString()
Fadwa
7

Mongo envía el documento completo como un objeto de devolución de llamada para que pueda obtenerlo solo desde allí.

por ejemplo

collection.save(function(err,room){
  var newRoomId = room._id;
  });
Saurabh Chandra Patel
fuente
4

Ahora puede usar el método insertOne y en el resultado de la promesa.

ktretyak
fuente
¿Podría proporcionar un ejemplo de código? ¿De dónde proviene este objeto de resultado?
JSideris
@JSideris, como puede ver en el método de especificación insertOne () , este método acepta tres parámetros (doc, options, callback). El tercer parámetro: una devolución de llamada, que toma dos parámetros (error, result) . Y resultesto es lo que está buscando.
ktretyak
2

@JSideris, código de muestra para obtener insertId.

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

si quieres tomar "_id" usa simpley

result.insertedId.toString() 

// toString se convertirá de hexadecimal

Hamit YILDIRIM
fuente
Eso es lo que estaba buscando. Gracias.
Fadwa
Sí, debe haber habido un cambio de versión ya que las otras respuestas que no mencionan result.insertedIdes un ObjectIDobjeto de tipo. .toString()convertirá este objeto en un UUID real.
Dylan Pierce
0

Puede usar funciones asíncronas para obtener el campo _id automáticamente sin manipular el objeto de datos:

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

  await db.collection('users', data )

  return data
}

Devuelve datos:

{
  _id: '5dbff150b407cc129ab571ca',
  name: 'John'
}
beytarovski
fuente
0

Otra forma de hacerlo en función asincrónica:

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;
Yohan W. Dunon
fuente