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

MongoDB เปรียบเทียบ 2 Field ด้วย $where และ JavaScript Function

Operator $where ใน MongoDB อนุญาตให้ใช้ JavaScript Expression เพื่อเปรียบเทียบ Field ระหว่างกัน หรือทำ Operation ที่ซับซ้อน เนื้อหานี้สาธิตการเปรียบเทียบ FirstName1 และ FirstName2 แบบ Case-Insensitive

ตัวอย่างข้อมูลทดสอบ

> db.demo7.insertOne({"FirstName1":"JOHN","FirstName2":"John"});
{ "acknowledged": true, "insertedId": ObjectId("5e0ccd1a25ddae1f53b6222f") }

> db.demo7.insertOne({"FirstName1":"Carol","FirstName2":"Mike"});
{ "acknowledged": true, "insertedId": ObjectId("5e0ccd2725ddae1f53b62230") }

> db.demo7.insertOne({"FirstName1":"bob","FirstName2":"BOB"});
{ "acknowledged": true, "insertedId": ObjectId("5e0ccd3225ddae1f53b62231") }

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

> db.demo7.find();
{
  "_id": ObjectId("5e0ccd1a25ddae1f53b6222f"),
  "FirstName1": "JOHN", "FirstName2": "John"
}
{
  "_id": ObjectId("5e0ccd2725ddae1f53b62230"),
  "FirstName1": "Carol", "FirstName2": "Mike"
}
{
  "_id": ObjectId("5e0ccd3225ddae1f53b62231"),
  "FirstName1": "bob", "FirstName2": "BOB"
}

Query $where เปรียบเทียบ Case-Insensitive

> db.demo7.find({
  $where: "this.FirstName1.toLowerCase() == this.FirstName2.toLowerCase()"
});

ผลลัพธ์ (Match 2 รายการ)

{
  "_id": ObjectId("5e0ccd1a25ddae1f53b6222f"),
  "FirstName1": "JOHN", "FirstName2": "John"
}
{
  "_id": ObjectId("5e0ccd3225ddae1f53b62231"),
  "FirstName1": "bob", "FirstName2": "BOB"
}

คำอธิบายและข้อควรระวัง

  • $where ใช้ JavaScript Engine ประเมิน Expression ต่อทุก Document
  • this = Current Document ใน Context
  • Performance: ช้ามาก - ไม่ใช้ Index, ต้อง Full Collection Scan, JavaScript Overhead สูง
  • Security: Risk ของ Injection หากรับ Input จาก User - ต้อง Sanitize อย่างเคร่งครัด
  • Alternative ดีกว่า (MongoDB 3.6+): ใช้ $expr กับ Aggregation Operators:
    db.demo7.find({
      $expr: {
        $eq: [
          { $toLower: "$FirstName1" },
          { $toLower: "$FirstName2" }
        ]
      }
    })
    • ใช้ Index ได้ (ถ้ามี Index บน Field ที่เกี่ยวข้อง)
    • รันใน Query Engine โดยตรง (ไม่ใช้ JavaScript)
    • รองรับ Operators: $eq, $gt, $lt, $add, $subtract, $concat, etc.
  • Collation ก็ทำ Case-Insensitive ได้: .collation({locale:"en", strength:2})

เมื่อไหร่ควรใช้ $where

  • Logic ที่ซับซ้อนเกิน $expr (เช่น Math Complex, Regex ใน JS)
  • One-time Admin Script / Maintenance (ไม่ใช่ Production Query)
  • Collection เล็กมาก (< 10k Docs)