Отримайте _id вставленого документа в базу даних Mongo в NodeJS


100

Я використовую NodeJS для вставки документів у MongoDB. Використовуючи collection.insertя можу вставити документ у базу даних, як у цьому коді:

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

Як я можу отримати _idвставлений об'єкт?

Чи є спосіб отримати _idбез вставлення останнього об'єкта _id?

Припускаючи, що одночасно багато людей отримують доступ до бази даних, я не можу бути впевнений, що останній ідентифікатор - це ідентифікатор вставленого об’єкта.

Відповіді:


88

Існує другий параметр зворотного виклику, collection.insertякий поверне вкладені документи або документи, у яких повинні бути _ids.

Спробуйте:

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

і перевірте консоль, щоб побачити, що я маю на увазі.


4
Зворотний виклик фактично повертає масив вставлених документів. Отже, якщо ви вставили один документ, ви можете отримати доступ до вставленої записи, як показано нижче. collection.insert ({name: "David", назва: "Про MongoDB"}, функція (помилка, записи) {console.log ("Запис додано як" + записи [0] ._ id);}); Ref: mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
Rohit Singh Sengar


посилання не приводить нікуди корисно
davidhadas

Я не знаю, чи це загальне чи працює лише в метеорі, але коли ви викликаєте collection.insert (object), він негайно повертає ідентифікатор вставленого об'єкта.
vantesllar

4
docsInserted не повертає _id для мене. він повертається для мене {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "izboraId": "7fffffff0000000000000005"}
user1709076

90

Коротший спосіб, ніж використання другого параметра для зворотного виклику collection.insert, буде використання, objectToInsert._idяке повертає _id(всередині функції зворотного виклику, припускаючи, що це була успішна операція).

Драйвер Mongo для NodeJS додає _idполе до оригінальної посилання на об'єкт, тому легко отримати вставлений ідентифікатор за допомогою оригінального об'єкта:

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

4
Дуже проникливий дякую. Не вдалося знайти цю інформацію ніде більше з моменту зміни параметрів зворотного дзвінка.
Бред Хайн

@BradHein Ласкаво просимо! Ймовірно, драйвер MongoDB змінює посилання на об'єкт, тому він також змінюється тут. :)
Ionică Bizău

Ваш код невірний, де ви говорите var objectId = objectToInsert._id; ви мали на увазі сказати var objectId = objectInserted._id;
Енді Лоренц

3
@AndyLorenz Що таке objectInserted? Я думаю, ви пропускаєте саме цю відповідь: драйвер Mongo додає _idполе до оригінального об'єкта. Я редагував відповідь, щоб користуватися objectToInsertвсюди. Сподіваюсь, зараз все зрозуміліше. :)
Ionică Bizău

1
ПРИМІТКА: insert()застаріло. Використовуйте insertOne()замість цього
evilReiko

16

Як сказав ktretyak, найкращим способом отримання вставленого ідентифікатора документа є використання властивості insertId на об'єкті результату. У моєму випадку результат._id не працював, тому мені довелося використовувати наступне:

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

Це те саме, якщо ви використовуєте зворотній зв'язок.


13

Я фактично зробив console.log () для другого параметра у функції зворотного виклику для вставки. Насправді багато інформації повертається крім самого вставленого об'єкта. Отже, наведений нижче код пояснює, як можна отримати доступ до його ідентифікатора.

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
       }
});

Це виводить an ObjectID {_bsontype: "ObjectID", id: Buffer(12)}. Як я можу використовувати його, щоб отримати фактичний ідентифікатор, який знаходиться в базі даних? ... Знайшов відповідь в іншому коментарі: Використовуватиresult.insertedId.toString()
Fadwa

7

Монго надсилає повний документ у якості виклику, тому ви можете просто отримати його лише звідти.

наприклад

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

4

Тепер ви можете скористатися методом insertOne та обещаним результатом.insertedId


Чи можете ви надати приклад коду? Звідки цей об’єкт результату?
JSideris

@JSideris, як ви бачите в методі специфікації insertOne () , цей метод приймає три параметри (doc, options, callback). Третій параметр - зворотний виклик, який приймає два параметри (error, result) . І result- це те, що ви шукаєте.
ктретяк

2

@JSideris, зразок коду для отримання insertId.

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

2

якщо ви хочете взяти "_id", використовуйте просто

result.insertedId.toString() 

// toString перетворить із шістнадцяткової


Ось що я шукав. Дякую.
Fadwa

Так, мала бути зміна версії, оскільки в інших відповідях, які не згадуються, result.insertedIdє ObjectIDоб'єктом типу. .toString()перетворить цей об'єкт у справжній UUID.
Ділан Пірс

0

Ви можете використовувати функції асинхронізації, щоб автоматично отримати поле _id, не маніпулюючи об'єктом даних:

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

  await db.collection('users', data )

  return data
}

Повертає дані:

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

0

Ще один спосіб зробити це у функції асинхронізації:

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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.