รับ _id ของเอกสารที่แทรกในฐานข้อมูล Mongo ใน NodeJS


101

ฉันใช้ NodeJS เพื่อแทรกเอกสารใน MongoDB การใช้collection.insertฉันสามารถแทรกเอกสารลงในฐานข้อมูลเช่นในรหัสนี้:

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

ฉันจะรับ_idวัตถุแทรกได้อย่างไร

มีวิธีใดบ้างในการรับ_idโดยไม่ต้องใส่วัตถุล่าสุด_id?

สมมติว่าในเวลาเดียวกันผู้คนจำนวนมากเข้าถึงฐานข้อมูลฉันไม่แน่ใจว่า id ล่าสุดคือ id ของวัตถุที่ใส่เข้าไป

คำตอบ:


88

มีพารามิเตอร์ที่สองสำหรับการเรียกกลับcollection.insertซึ่งจะส่งคืนเอกสารหรือเอกสารที่แทรกซึ่งควรมี _ids

ลอง:

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

และตรวจสอบคอนโซลเพื่อดูว่าฉันหมายถึงอะไร


4
Callback ส่งคืนอาร์เรย์ของเอกสารที่ใส่เข้าไป ดังนั้นหากคุณใส่เอกสารเดียวคุณสามารถเข้าถึงบันทึกที่แทรกได้ดังต่อไปนี้ 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
มีการเปลี่ยนแปลง Callbacks API: mongodb.github.io/node-mongodb-native/2.0/api/…
tenbits

ลิงค์ไม่นำไปสู่ทุกที่ที่มีประโยชน์
davidhadas

ฉันไม่รู้ว่านี่เป็นเรื่องทั่วไปหรือใช้ได้เฉพาะในดาวตก แต่เมื่อคุณเรียก collection.insert (object) มันจะส่งคืน id ของวัตถุที่แทรกทันที
vantesllar

4
docsInserted ไม่ส่งคืน _id ให้ฉัน มันคืนค่าให้ฉัน {"ok": 1, "n": 1, "opTime": {"ts": "6361004504208375809", "t": 5}, "ElectionId": "7fffffff0000000000000005"}
user1709076

91

วิธีที่สั้นกว่าการใช้พารามิเตอร์ที่สองสำหรับการเรียกกลับของcollection.insertจะใช้objectToInsert._idที่ส่งกลับ_id(ภายในฟังก์ชันเรียกกลับโดยสมมติว่าเป็นการดำเนินการสำเร็จ)

ไดรเวอร์ Mongo สำหรับ NodeJS ต่อท้าย_idฟิลด์กับการอ้างอิงอ็อบเจ็กต์ดั้งเดิมดังนั้นจึงเป็นเรื่องง่ายที่จะรับ 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;
Andy Lorenz

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

มันก็เหมือนกันถ้าคุณใช้การโทรกลับ


13

จริงๆแล้วฉันทำ console.log () สำหรับพารามิเตอร์ที่สองในฟังก์ชันเรียกกลับสำหรับแทรก จริงๆแล้วมีข้อมูลมากมายที่ส่งคืนนอกเหนือจากวัตถุที่แทรกเอง ดังนั้นโค้ดด้านล่างนี้จะอธิบายถึงวิธีการเข้าถึง id

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)}ไฟล์. ฉันจะใช้มันเพื่อรับ id จริงที่อยู่ในฐานข้อมูลได้อย่างไร ... พบคำตอบในความคิดเห็นอื่น: ใช้result.insertedId.toString()
Fadwa

7

Mongo ส่งเอกสารฉบับสมบูรณ์เป็น callbackobject เพื่อให้คุณได้รับจากที่นั่นเท่านั้น

ตัวอย่างเช่น

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 โค้ดตัวอย่างสำหรับการแทรก ID

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

2

หากคุณต้องการใช้ "_id" ให้ใช้ simpley

result.insertedId.toString() 

// toString จะแปลงจากฐานสิบหก


นั่นคือสิ่งที่ฉันกำลังมองหา ขอบคุณ.
Fadwa

ใช่จะต้องมีการเปลี่ยนแปลงเวอร์ชันเนื่องจากคำตอบอื่น ๆ ที่ไม่ได้กล่าวถึงresult.insertedIdคือObjectIDวัตถุประเภท .toString()จะแปลงวัตถุนี้เป็น UUID จริง
Dylan Pierce

0

คุณสามารถใช้ฟังก์ชัน asyncเพื่อรับฟิลด์ _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;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.