Ottieni l'_id del documento inserito nel database Mongo in NodeJS


100

Uso NodeJS per inserire documenti in MongoDB. Utilizzando collection.insertposso inserire un documento nel database come in questo codice:

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

Come posso ottenere l' _idoggetto inserito?

C'è un modo per ottenere il _idsenza ottenere l'ultimo oggetto inserito _id?

Supponendo che nello stesso tempo molte persone accedano al database, non posso essere sicuro che l'ultimo id sia l'ID dell'oggetto inserito.

Risposte:


88

C'è un secondo parametro per la richiamata collection.insertche restituirà il documento oi documenti inseriti, che dovrebbero avere _ids.

Provare:

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

e controlla la console per vedere cosa intendo.


4
La richiamata restituisce effettivamente la matrice di documenti inseriti. Quindi, se hai inserito un singolo documento, puoi accedere al record inserito come di seguito. collection.insert ({name: "David", title: "About MongoDB"}, function (err, records) {console.log ("Record added as" + records [0] ._ id);}); Ref: mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
Rohit Singh Sengar


il collegamento non porta da nessuna parte utile
davidhadas

Non so se questo sia generale o funzioni solo in meteor, ma quando chiami collection.insert (object), restituisce immediatamente l'id dell'oggetto inserito.
vantesllar

4
docsInserted non restituisce un _id per me. restituisce per me {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "ElectionId": "7fffffff0000000000000005"}
user1709076

90

Un modo più breve rispetto all'utilizzo del secondo parametro per il callback di collection.insertsarebbe using objectToInsert._idthat returns the _id(all'interno della funzione di callback, supponendo che sia stata un'operazione riuscita).

Il driver Mongo per NodeJS aggiunge il _idcampo al riferimento all'oggetto originale, quindi è facile ottenere l'id inserito utilizzando l'oggetto originale:

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

4
Grazie molto perspicace. Impossibile trovare queste informazioni da nessun'altra parte dopo la modifica dei parametri di callback.
Brad Hein

@BradHein Sei il benvenuto! Probabilmente il driver MongoDB modifica il riferimento all'oggetto, quindi viene modificato anche qui. :)
Ionică Bizău

Il tuo codice è sbagliato, dove dici var objectId = objectToInsert._id; volevi dire var objectId = objectInserted._id;
Andy Lorenz

3
@ AndyLorenz Cos'è objectInserted? Immagino che ti manchi esattamente il punto di questa risposta: il driver Mongo aggiunge il _idcampo all'oggetto originale. Ho modificato la risposta per usarla objectToInsertovunque. Spero che le cose siano più chiare ora. :)
Ionică Bizău

1
NOTA: insert()è deprecato. Usa insertOne()invece
evilReiko

16

Come ha detto ktretyak, per ottenere l'ID del documento inserito il modo migliore è usare la proprietà insertId sull'oggetto risultato. Nel mio caso result._id non ha funzionato, quindi ho dovuto usare quanto segue:

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

È la stessa cosa se usi i callback.


13

In realtà ho fatto un console.log () per il secondo parametro nella funzione di callback per l'inserimento. In realtà ci sono molte informazioni restituite oltre all'oggetto inserito stesso. Quindi il codice seguente spiega come puoi accedere al suo 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
       }
});

Questo genera un file ObjectID {_bsontype: "ObjectID", id: Buffer(12)}. Come posso usarlo per ottenere l'ID effettivo che si trova nel database? ... Ho trovato la risposta in un altro commento: Usaresult.insertedId.toString()
Fadwa

7

Mongo invia il documento completo come oggetto callback in modo che tu possa semplicemente ottenerlo solo da lì.

per esempio

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

4

Ora puoi usare il metodo insertOne e in result.insertedId di promise


Potresti fornire un esempio di codice? Da dove viene questo oggetto risultato?
JSideris

@JSideris, come puoi vedere nel metodo di specifica insertOne () , questo metodo accetta tre parametri (doc, options, callback). Il terzo parametro: un callback, che accetta due parametri (error, result) . E resultquesto è quello che stai cercando.
ktretyak

2

@JSideris, codice di esempio per ottenere insertId.

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

2

se vuoi prendere "_id" usa semplicemente

result.insertedId.toString() 

// toString convertirà da hex


Questo è quello che stavo cercando. Grazie.
Fadwa,

Sì, ci deve essere stato un cambio di versione poiché le altre risposte non menzionate result.insertedIdè un ObjectIDoggetto tipo. .toString()convertirà questo oggetto in un vero UUID.
Dylan Pierce

0

È possibile utilizzare funzioni asincrone per ottenere automaticamente il campo _id senza manipolare l'oggetto dati:

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

  await db.collection('users', data )

  return data
}

Restituisce dati:

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

0

Un altro modo per farlo nella funzione asincrona:

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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.