Obtenez le _id du document inséré dans la base de données Mongo dans NodeJS

100

J'utilise NodeJS pour insérer des documents dans MongoDB. En utilisant collection.insertje peux insérer un document dans la base de données comme dans ce code:

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

Comment puis-je obtenir l' _idobjet inséré?

Existe-t-il un moyen d'obtenir le _idsans insérer le dernier objet _id?

En supposant que dans le même temps beaucoup de gens accèdent à la base de données, je ne peux pas être sûr que le dernier identifiant est l'identifiant de l'objet inséré.

Ionică Bizău
la source

Réponses:

88

Il existe un deuxième paramètre pour le rappel collection.insertqui renverra le ou les documents insérés, qui devraient avoir _ids.

Essayer:

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

et vérifiez la console pour voir ce que je veux dire.

Georgedyer
la source
4
Le rappel renvoie en fait un tableau de documents insérés. Ainsi, si vous avez inséré un seul document, vous pouvez accéder à l'enregistrement inséré comme ci-dessous. collection.insert ({nom: "David", titre: "À propos de MongoDB"}, function (err, records) {console.log ("Record added as" + records [0] ._ id);}); Réf: mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
Rohit Singh Sengar
2
L'API de rappel
tenbits
le lien ne mène nulle part utile
davidhadas
Je ne sais pas si cela est général ou ne fonctionne que dans meteor, mais lorsque vous appelez collection.insert (objet), il renvoie immédiatement l'id de l'objet inséré.
vantesllar
4
docsInserted ne renvoie pas de _id pour moi. il renvoie pour moi {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "choixId": "7fffffff0000000000000005"}
user1709076
90

Un moyen plus court que d'utiliser le deuxième paramètre pour le rappel de collection.insertserait d'utiliser objectToInsert._idqui renvoie le _id(à l'intérieur de la fonction de rappel, en supposant que l'opération a réussi).

Le pilote Mongo pour NodeJS ajoute le _idchamp à la référence d'objet d'origine, il est donc facile d'obtenir l'ID inséré à l'aide de l'objet d'origine:

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
la source
4
Merci très perspicace. Impossible de trouver ces informations ailleurs depuis la modification des paramètres de rappel.
Brad Hein
@BradHein De rien! Le pilote MongoDB modifie probablement la référence de l'objet, il est donc modifié ici aussi. :)
Ionică Bizău
Votre code est faux, où vous dites var objectId = objectToInsert._id; vous vouliez dire var objectId = objectInserted._id;
Andy Lorenz
3
@AndyLorenz Qu'est-ce que c'est objectInserted? Je suppose que vous manquez exactement le point de cette réponse: le pilote Mongo ajoute le _idchamp à l'objet d'origine. J'ai édité la réponse pour l'utiliser objectToInsertpartout. J'espère que les choses sont plus claires maintenant. :)
Ionică Bizău
1
REMARQUE: insert()est obsolète. Utiliser à la insertOne()place
evilReiko
16

Comme l'a dit ktretyak, pour obtenir l'ID du document inséré, le meilleur moyen est d'utiliser la propriété insertId sur l'objet résultat. Dans mon cas, result._id ne fonctionnait pas, j'ai donc dû utiliser ce qui suit:

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

C'est la même chose si vous utilisez des rappels.

Serjuice
la source
13

J'ai en fait fait un console.log () pour le deuxième paramètre de la fonction de rappel pour l'insertion. Il y a en fait beaucoup d'informations renvoyées en dehors de l'objet inséré lui-même. Le code ci-dessous explique donc comment accéder à son identifiant.

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
la source
Cela génère un fichier ObjectID {_bsontype: "ObjectID", id: Buffer(12)}. Comment puis-je l'utiliser pour obtenir l'identifiant réel qui se trouve dans la base de données? ... J'ai trouvé la réponse dans un autre commentaire: Utilisationresult.insertedId.toString()
Fadwa
7

Mongo envoie le document complet en tant qu'objet de rappel afin que vous puissiez simplement l'obtenir à partir de là uniquement.

par exemple

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

Vous pouvez maintenant utiliser la méthode insertOne et le résultat de la promesse.

ktretyak
la source
Pouvez-vous fournir un exemple de code? D'où vient cet objet de résultat?
JSideris
@JSideris, comme vous pouvez le voir dans la méthode de spécification insertOne () , cette méthode accepte trois paramètres (doc, options, callback). Le troisième paramètre - un rappel, qui prend deux paramètres (error, result) . Et result- c'est ce que vous recherchez.
ktretyak le
2

@JSideris, exemple de code pour obtenir insertId.

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

si vous voulez prendre "_id" utilisez simpley

result.insertedId.toString() 

// toString convertira de hexadécimal

Hamit YILDIRIM
la source
C'est ce que je cherchais. Je vous remercie.
Fadwa
Oui, il doit y avoir eu un changement de version puisque les autres réponses ne mentionnent pas result.insertedIdun ObjectIDobjet de type. .toString()convertira cet objet en un véritable UUID.
Dylan Pierce le
0

Vous pouvez utiliser des fonctions asynchrones pour obtenir automatiquement le champ _id sans manipuler l'objet de données:

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

  await db.collection('users', data )

  return data
}

Renvoie des données:

{
  _id: '5dbff150b407cc129ab571ca',
  name: 'John'
}
Beytarovski
la source
0

Une autre façon de le faire en fonction asynchrone:

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
la source