Lấy _id của tài liệu được chèn trong cơ sở dữ liệu Mongo trong NodeJS


100

Tôi sử dụng NodeJS để chèn tài liệu trong MongoDB. Sử dụng, collection.inserttôi có thể chèn một tài liệu vào cơ sở dữ liệu như trong mã này:

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

Làm cách nào để lấy _idđối tượng đã chèn?

Có cách nào để lấy _idmà không cần chèn đối tượng mới nhất _idkhông?

Giả sử rằng trong cùng một thời điểm có nhiều người truy cập vào cơ sở dữ liệu, tôi không thể chắc chắn rằng id mới nhất là id của đối tượng được chèn vào.

Câu trả lời:


88

Có một tham số thứ hai cho lệnh gọi lại collection.insertsẽ trả về tài liệu hoặc tài liệu được chèn vào, phải có _ids.

Thử:

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

và kiểm tra bảng điều khiển để xem tôi muốn nói gì.


4
Gọi lại thực sự trả về mảng tài liệu đã chèn. Vì vậy, nếu bạn đã chèn một tài liệu thì bạn có thể truy cập vào bản ghi đã chèn như bên dưới. collection.insert ({name: "David", title: "Giới thiệu về MongoDB"}, function (err, records) {console.log ("Đã thêm bản ghi dưới dạng" + records [0] ._ id);}); Tham khảo: mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
Rohit Singh Sengar

2
API gọi lại đã thay đổi: mongodb.github.io/node-mongodb-native/2.0/api/…
tenbits

liên kết không dẫn đến bất kỳ nơi nào hữu ích
davidhadas

Tôi không biết điều này là chung chung hay chỉ hoạt động trong sao băng, nhưng khi bạn gọi collection.insert (object), nó trả về id của đối tượng được chèn ngay lập tức.
vantesllar

4
docsInserted không trả lại _id cho tôi. nó trả về cho tôi {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "bầu cử": "7fffffff0000000000000005"}
user1709076

90

Một cách ngắn hơn so với việc sử dụng tham số thứ hai cho lệnh gọi lại của collection.insertsẽ là sử dụng objectToInsert._idtrả về _id(bên trong hàm gọi lại, giả sử đó là một hoạt động thành công).

Trình điều khiển Mongo cho NodeJS gắn _idtrường vào tham chiếu đối tượng ban đầu, vì vậy, thật dễ dàng để lấy id được chèn bằng cách sử dụng đối tượng gốc:

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

4
Cảm ơn bạn rất sâu sắc. Không thể tìm thấy thông tin này ở bất kỳ nơi nào khác vì sự thay đổi trong các thông số gọi lại.
Brad Hein

@BradHein Không có chi! Có lẽ trình điều khiển MongoDB sửa đổi tham chiếu đối tượng, vì vậy nó cũng được sửa đổi ở đây. :)
Ionică Bizău,

Mã của bạn sai, trong đó bạn nói var objectId = objectToInsert._id; bạn muốn nói var objectId = objectInserted._id;
Andy Lorenz

3
@AndyLorenz là objectInsertedgì? Tôi đoán bạn đang thiếu chính xác điểm của câu trả lời này: trình điều khiển Mongo gắn _idtrường vào đối tượng ban đầu. Tôi đã chỉnh sửa câu trả lời để sử dụng objectToInsertở mọi nơi. Hy vọng mọi thứ rõ ràng hơn bây giờ. :)
Ionică Bizău

1
LƯU Ý: insert()không được dùng nữa. Sử dụng insertOne()thay vì
evilReiko

16

Như ktretyak đã nói, để có được ID của tài liệu được chèn, cách tốt nhất là sử dụng thuộc tính insertId trên đối tượng kết quả. Trong trường hợp của tôi, result._id không hoạt động nên tôi phải sử dụng như sau:

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

Điều tương tự nếu bạn sử dụng các lệnh gọi lại.


13

Tôi thực sự đã thực hiện một console.log () cho tham số thứ hai trong hàm gọi lại để chèn. Thực tế có rất nhiều thông tin được trả về ngoài chính đối tượng được chèn. Vì vậy, đoạn mã bên dưới giải thích cách bạn có thể truy cập id của nó.

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

Kết quả này là một ObjectID {_bsontype: "ObjectID", id: Buffer(12)}. ? Làm thế nào tôi có thể sử dụng nó để nhận được id thực tế đó là trong cơ sở dữ liệu ... Tìm thấy câu trả lời trong bình luận khác: Sử dụngresult.insertedId.toString()
Fadwa

7

Mongo gửi tài liệu hoàn chỉnh dưới dạng callbackobject để bạn chỉ có thể lấy nó từ đó.

ví dụ

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

4

Bây giờ bạn có thể sử dụng phương thức insertOne và trong result.insertedId


Bạn có thể cung cấp một ví dụ về mã? Đối tượng kết quả này đến từ đâu?
JSideris

@JSideris, như bạn có thể thấy trong phương thức đặc tả insertOne () , phương thức này chấp nhận ba tham số (doc, options, callback). Tham số thứ ba - một cuộc gọi lại, nhận hai tham số (error, result) . Và result- đây là những gì bạn đang tìm kiếm.
ktretyak

2

@JSideris, mã mẫu để nhận được insertId.

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

2

nếu bạn muốn lấy "_id", hãy sử dụng simpley

result.insertedId.toString() 

// toString sẽ chuyển đổi từ hex


Đó là những gì tôi đang tìm kiếm. Cảm ơn bạn.
Fadwa

Phải, phải có một sự thay đổi phiên bản vì các câu trả lời khác không đề cập đến result.insertedIdlà một ObjectIDđối tượng kiểu. .toString()sẽ chuyển đổi đối tượng này thành một UUID thực.
Dylan Pierce

0

Bạn có thể sử dụng các hàm không đồng bộ để tự động nhận trường _id mà không cần thao tác đối tượng dữ liệu:

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

  await db.collection('users', data )

  return data
}

Trả về dữ liệu:

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

0

Một cách khác để làm điều đó trong hàm không đồng bộ:

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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.