Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

MongoDB: ค้นหาเอกสารเดียวที่ตรงเงื่อนไขด้วย findOne()

Method findOne() ใน MongoDB คืนค่า เอกสารเดียว ที่ตรงเงื่อนไข (ตัวแรกตาม natural order) เหมาะสำหรับกรณีที่รู้ว่ามีผลลัพธ์เพียงอย่างเดียวหรือต้องการแค่ตัวอย่าง

สร้างคอลเลกชันและข้อมูลตัวอย่าง (มี EmployeeId ซ้ำ)

> db.demo116.insertOne({"EmployeeId":101,"EmployeeName":"John"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2eff98d8f64a552dae635b") }
> db.demo116.insertOne({"EmployeeId":102,"EmployeeName":"Bob"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2eff9fd8f64a552dae635c") }
> db.demo116.insertOne({"EmployeeId":103,"EmployeeName":"David"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2effa5d8f64a552dae635d") }
> db.demo116.insertOne({"EmployeeId":102,"EmployeeName":"Mike"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2effb7d8f64a552dae635e") }

แสดงข้อมูลทั้งหมด

> db.demo116.find();

ผลลัพธ์: 4 เอกสาร EmployeeId=102 มี 2 คน (Bob, Mike)

Query findOne หา EmployeeId=102

> db.demo116.findOne({"EmployeeId":102});

ผลลัพธ์

{ "_id" : ObjectId("5e2eff9fd8f64a552dae635c"), "EmployeeId" : 102, "EmployeeName" : "Bob" }

คืนค่าเฉพาะ Bob (เอกสารแรกที่เจอ) ไม่รวม Mike แม้ EmployeeId เดียวกัน

ความแตกต่าง find() vs findOne()

findOne() กับ Projection

// ดึงเฉพาะ Name
db.demo116.findOne({EmployeeId: 102}, {projection: {EmployeeName: 1, _id: 0}})
// { "EmployeeName" : "Bob" }

findOne() ใน Application Code (Node.js)

// Callback style
db.collection('demo116').findOne({EmployeeId: 102}, (err, doc) => {
  if (err) throw err;
  console.log(doc);
});

// Promise/Async style
const doc = await db.collection('demo116').findOne({EmployeeId: 102});

กรณีไม่เจอเอกสาร

> db.demo116.findOne({EmployeeId: 999});
// null (ไม่ได้ error)

Sort กับ findOne (สำคัญ!)

findOne ไม่รับ sort parameter ตรงๆ ต้องใช้ find().sort().limit(1):

// หา EmployeeId=102 ที่มี _id ใหม่สุด (insert ล่าสุด)
db.demo116.find({EmployeeId: 102}).sort({_id: -1}).limit(1)
// หรือ
db.demo116.findOne({EmployeeId: 102}, {sort: {_id: -1}})  // driver บางตัวรองรับ

สรุป: findOne() ใช้สำหรับดึง 1 document อย่างรวดเร็ว เหมาะกับ lookup by _id หรือ unique field

Methodคืนค่าใช้เมื่อไหร่
find()Cursor (iterable)ต้องการทุกเอกสารที่ตรง เลื่อนหน้า (pagination)
findOne()Document (object) หรือ nullต้องการแค่ 1 เอกสาร, check exists, get by _id