Uzyskaj identyfikator _id wstawionego dokumentu w bazie danych Mongo w NodeJS

100

Używam NodeJS do wstawiania dokumentów do MongoDB. Używając collection.insertI mogę wstawić dokument do bazy danych jak w tym kodzie:

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

Jak mogę uzyskać _idwstawiony obiekt?

Czy jest jakiś sposób na pobranie _idbez wstawiania najnowszego obiektu _id?

Zakładając, że w tym samym czasie wiele osób uzyskuje dostęp do bazy danych, nie mogę być pewien, czy najnowszy identyfikator to identyfikator wstawionego obiektu.

Ionică Bizău
źródło

Odpowiedzi:

88

Istnieje drugi parametr wywołania zwrotnego collection.insert, który zwróci wstawiony dokument lub dokumenty, które powinny mieć _ids.

Próbować:

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

i sprawdź w konsoli, co mam na myśli.

georgedyer
źródło
4
Callback faktycznie zwraca tablicę wstawionych dokumentów. Tak więc, jeśli wstawiłeś pojedynczy dokument, możesz uzyskać dostęp do wstawionego rekordu, jak poniżej. 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
2
Zmieniło się API wywołań zwrotnych
tenbit
link nie prowadzi do niczego przydatnego
davidhadas
Nie wiem, czy to jest ogólne, czy działa tylko w meteor, ale kiedy wywołujesz collection.insert (obiekt), zwraca ona od razu identyfikator wstawionego obiektu.
vantesllar
4
docsInserted nie zwraca dla mnie _id. zwraca dla mnie {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "electionId": "7fffffff0000000000000005"}
user1709076
90

Krótszym sposobem niż użycie drugiego parametru dla wywołania zwrotnego collection.insertbyłoby użycie, objectToInsert._idktóry zwraca_id (wewnątrz funkcji zwrotnej, zakładając, że była to operacja pomyślna).

Sterownik Mongo dla NodeJS dołącza _idpole do oryginalnego odniesienia do obiektu, więc łatwo jest uzyskać wstawiony identyfikator przy użyciu oryginalnego obiektu:

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
źródło
4
Bardzo wnikliwe dziękuję. Nie można znaleźć tych informacji nigdzie indziej od czasu zmiany parametrów wywołania zwrotnego.
Brad Hein
@BradHein Nie ma za co! Prawdopodobnie sterownik MongoDB modyfikuje odniesienie do obiektu, więc tutaj również jest modyfikowany. :)
Ionică Bizău
Twój kod jest nieprawidłowy. Mówisz var objectId = objectToInsert._id; chciałeś powiedzieć var ​​objectId = objectInserted._id;
Andy Lorenz
3
@AndyLorenz Co to jest objectInserted? Wydaje mi się, że brakuje Ci dokładnie sensu tej odpowiedzi: sterownik Mongo dołącza _idpole do oryginalnego obiektu. Zredagowałem odpowiedź, aby używać jej objectToInsertwszędzie. Mam nadzieję, że teraz wszystko jest jaśniejsze. :)
Ionică Bizău
1
UWAGA: insert()jest przestarzałe. Użyj insertOne()zamiast tego
evilReiko
16

Jak powiedział ktretyak, najlepszym sposobem uzyskania identyfikatora wstawionego dokumentu jest użycie właściwości insertId na obiekcie wynikowym. W moim przypadku result._id nie działał, więc musiałem użyć następującego:

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

To samo dotyczy wywołań zwrotnych.

Serjuice
źródło
13

Właściwie zrobiłem console.log () dla drugiego parametru w funkcji zwrotnej dla wstawiania. W rzeczywistości zwracanych jest wiele informacji poza samym wstawionym obiektem. Poniższy kod wyjaśnia, jak uzyskać dostęp do jego identyfikatora.

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
źródło
Wyprowadza plik ObjectID {_bsontype: "ObjectID", id: Buffer(12)}. Jak mogę go użyć, aby uzyskać rzeczywisty identyfikator znajdujący się w bazie danych? ... Odpowiedź znalazłem w innym komentarzu: Użyjresult.insertedId.toString()
Fadwa
7

Mongo wysyła cały dokument jako obiekt wywołania zwrotnego, więc możesz go po prostu pobrać tylko stamtąd.

na przykład

collection.save(function(err,room){
  var newRoomId = room._id;
  });
Saurabh Chandra Patel
źródło
4

Teraz możesz użyć metody insertOne i wyniku promise .insertedId

ktretyak
źródło
Czy możesz podać przykład kodu? Skąd pochodzi ten obiekt wynikowy?
JSideris
@JSideris, jak widać w specyfikacji metody insertOne () , metoda ta przyjmuje trzy parametry (doc, options, callback). Trzeci parametr - wywołanie zwrotne, które przyjmuje dwa parametry (error, result) . I result- tego właśnie szukasz.
ktretyak
2

@JSideris, przykładowy kod do pobierania insertId.

db.collection(COLLECTION).insertOne(data, (err, result) => {
    if (err) 
      return err;
    else 
      return result.insertedId;
  });
Pyae Sone
źródło
2

jeśli chcesz wziąć „_id”, użyj prostego

result.insertedId.toString() 

// toString skonwertuje z hex

Hamit YILDIRIM
źródło
Właśnie tego szukałem. Dziękuję Ci.
Fadwa
Tak, musiała nastąpić zmiana wersji, ponieważ inne odpowiedzi nie wspominają result.insertedIdo ObjectIDobiekcie typu. .toString()przekształci ten obiekt w rzeczywisty UUID.
Dylan Pierce
0

Możesz użyć funkcji asynchronicznych, aby automatycznie uzyskać pole _id bez manipulowania obiektem danych:

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

  await db.collection('users', data )

  return data
}

Zwraca dane:

{
  _id: '5dbff150b407cc129ab571ca',
  name: 'John'
}
beytarovski
źródło
0

Inny sposób na zrobienie tego w funkcji asynchronicznej:

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
źródło