Получить _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 ({имя: "Дэвид", заголовок: "О MongoDB"}, функция (ошибка, записи) {console.log ("Запись добавлена ​​как" + records [0] ._ id);}); Ссылка: mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
Рохит Сингх Сенгар,
2
API обратных
вызовов
ссылка никуда полезная не ведет
давидхадас 08
Я не знаю, является ли это общим или работает только в метеоре, но когда вы вызываете collection.insert (object), он сразу же возвращает идентификатор вставленного объекта.
vantesllar
4
docsInserted не возвращает мне _id. он возвращает мне {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "selectionId": "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
Очень глубокое спасибо. Не удалось найти эту информацию где-либо еще с момента изменения параметров обратного вызова.
Brad Hein
@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 для объекта результата. В моем случае result._id не работал, поэтому мне пришлось использовать следующее:

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

То же самое и с обратными вызовами.

Serjuice
источник
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
       }
});
Сидак
источник
Это выводит файл ObjectID {_bsontype: "ObjectID", id: Buffer(12)}. Как я могу использовать его , чтобы получить фактический идентификатор , который находится в базе данных ... Найден ответ на другой комментарий: Использованиеresult.insertedId.toString()
Fadwa
7

Mongo отправляет полный документ как объект обратного вызова, поэтому вы можете просто получить его только оттуда.

например

collection.save(function(err,room){
  var newRoomId = room._id;
  });
Саураб Чандра Патель
источник
4

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

ктретьяк
источник
Не могли бы вы привести пример кода? Откуда появился этот объект результата?
JSideris
@JSideris, как вы можете видеть в методе спецификации insertOne () , этот метод принимает три параметра (doc, options, callback). Третий параметр - обратный вызов, принимающий два параметра (error, result) . И result- это то, что вы ищете.
ktretyak
2

@JSideris, пример кода для получения InsertId.

db.collection(COLLECTION).insertOne(data, (err, result) => {
    if (err) 
      return err;
    else 
      return result.insertedId;
  });
Pyae Sone
источник
2

если вы хотите использовать _id, используйте simpley

result.insertedId.toString() 

// toString будет преобразовывать из шестнадцатеричного

Хамит ИЛДИРИМ
источник
Это то, что я искал. Спасибо.
Фадва
Да, должно быть , было изменение версии , так как другие ответы не говоря уже 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

Другой способ сделать это в функции async:

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;
Йохан В. Данон
источник