Rufen Sie die _id des eingefügten Dokuments in der Mongo-Datenbank in NodeJS ab

100

Ich benutze NodeJS, um Dokumente in MongoDB einzufügen. Mit collection.insertIch kann ein Dokument wie in diesem Code in die Datenbank einfügen:

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

Wie kann ich das _ideingefügte Objekt erhalten?

Gibt es eine Möglichkeit, das zu erhalten, _idohne das neueste Objekt einzufügen _id?

Angenommen, gleichzeitig greifen viele Personen auf die Datenbank zu, kann ich nicht sicher sein, ob die neueste ID die ID des eingefügten Objekts ist.

Ionică Bizău
quelle

Antworten:

88

Es gibt einen zweiten Parameter für den Rückruf collection.insert, der das oder die eingefügten Dokumente zurückgibt, die _ids haben sollten.

Versuchen:

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

und überprüfen Sie die Konsole, um zu sehen, was ich meine.

georgedyer
quelle
4
Callback gibt tatsächlich eine Reihe von eingefügten Dokumenten zurück. Wenn Sie also ein einzelnes Dokument eingefügt haben, können Sie wie folgt auf den eingefügten Datensatz zugreifen. collection.insert ({name: "David", title: "About MongoDB"}, function (err, records) {console.log ("Datensatz hinzugefügt als" + records [0] ._ id);}); Ref: mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
Rohit Singh Sengar
2
Die Callbacks-API hat sich geändert: mongodb.github.io/node-mongodb-native/2.0/api/…
Tenbits
Link führt nirgendwo nützlich
Davidhadas
Ich weiß nicht, ob dies allgemein ist oder nur in Meteor funktioniert, aber wenn Sie collection.insert (Objekt) aufrufen, wird die ID des eingefügten Objekts sofort zurückgegeben.
Vantesllar
4
docsInserted gibt für mich keine _id zurück. es gibt für mich zurück {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "choiceId": "7fffffff0000000000000005"}
user1709076
90

Ein kürzerer Weg als die Verwendung von zweiten Parametern für den Rückruf von collection.insertwäre mit , objectToInsert._iddass kehrt die _id(innerhalb der Callback - Funktion, es war ein erfolgreicher Betrieb angenommen).

Der Mongo-Treiber für NodeJS hängt das _idFeld an die ursprüngliche Objektreferenz an, sodass es einfach ist, die eingefügte ID mithilfe des ursprünglichen Objekts abzurufen :

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
quelle
4
Sehr aufschlussreich, danke. Diese Informationen konnten seit der Änderung der Rückrufparameter nirgendwo anders gefunden werden.
Brad Hein
@BradHein Gern geschehen! Wahrscheinlich ändert der MongoDB-Treiber die Objektreferenz, sodass sie auch hier geändert wird. :)
Ionică Bizău
Ihr Code ist falsch, wenn Sie var objectId = objectToInsert._id sagen; Sie wollten var objectId = objectInserted._id sagen;
Andy Lorenz
3
@AndyLorenz Was ist objectInserted? Ich denke, Sie verpassen genau den Punkt dieser Antwort: Der Mongo-Treiber hängt das _idFeld an das ursprüngliche Objekt an. Ich habe die Antwort so bearbeitet, dass sie objectToInsertüberall verwendet werden kann. Hoffe, die Dinge sind jetzt klarer. :)
Ionică Bizău
1
HINWEIS: insert()ist veraltet. Verwenden Sie insertOne()stattdessen
evilReiko
16

Wie ktretyak sagte, besteht die beste Möglichkeit, die ID des eingefügten Dokuments zu erhalten, darin, die Eigenschaft insertId für das Ergebnisobjekt zu verwenden. In meinem Fall hat result._id nicht funktioniert, daher musste ich Folgendes verwenden:

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

Es ist dasselbe, wenn Sie Rückrufe verwenden.

Serjuice
quelle
13

Ich habe tatsächlich eine console.log () für den zweiten Parameter in der Rückruffunktion zum Einfügen erstellt. Abgesehen vom eingefügten Objekt selbst werden tatsächlich viele Informationen zurückgegeben. Der folgende Code erklärt also, wie Sie auf die ID zugreifen können.

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
quelle
Dies gibt eine aus ObjectID {_bsontype: "ObjectID", id: Buffer(12)}. Wie kann ich es verwenden, um die tatsächliche ID in der Datenbank zu erhalten? ... Die Antwort in einem anderen Kommentar gefunden: Verwendenresult.insertedId.toString()
Fadwa
7

Mongo sendet das gesamte Dokument als Rückrufobjekt, sodass Sie es einfach nur von dort abrufen können.

beispielsweise

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

Jetzt können Sie die insertOne- Methode und in der result.insertedId des Versprechens verwenden

ktretyak
quelle
Könnten Sie ein Codebeispiel angeben? Woher kommt dieses Ergebnisobjekt?
JSideris
@JSideris, wie Sie in der Spezifikationsmethode insertOne () sehen können , akzeptiert diese Methode drei Parameter (doc, options, callback). Der dritte Parameter - ein Rückruf, der zwei Parameter akzeptiert (error, result) . Und result- das ist was Sie suchen.
Ktretyak
2

@JSideris, Beispielcode zum Einfügen der ID.

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

Wenn Sie "_id" nehmen möchten, verwenden Sie simpley

result.insertedId.toString() 

// toString konvertiert von hex

Hamit YILDIRIM
quelle
Das habe ich gesucht. Danke dir.
Fadwa
Ja, es muss eine Versionsänderung gegeben haben, da die anderen Antworten, die nicht erwähnt result.insertedIdwerden, ein ObjectIDTypobjekt sind. .toString()konvertiert dieses Objekt in eine echte UUID.
Dylan Pierce
0

Sie können asynchrone Funktionen verwenden , um das Feld _id automatisch abzurufen, ohne das Datenobjekt zu manipulieren:

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

  await db.collection('users', data )

  return data
}

Gibt Daten zurück:

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

Eine andere Möglichkeit, dies in der asynchronen Funktion zu tun:

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
quelle