MongoDB นิพจน์ปกติ ($regex) พร้อมตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

MongoDB นิพจน์ปกติ (Regular expressions) ทำหน้าที่จับคู่รูปแบบเพื่อค้นหาสตริงภายในเอกสาร โดยใช้ตัวดำเนินการ $regex, แฟล็ก $options สำหรับการไม่คำนึงถึงตัวพิมพ์ใหญ่เล็ก, ตัวยึดสำหรับการจับคู่ที่ตรงกันทุกประการ และตัวคั่นแบบสแลชเมื่อไม่ทราบค่าฟิลด์ที่แน่นอน

  • 🔍 $regex Operaทอร์: db.collection.find({field:{$regex:”pattern”}}) จะค้นหาเอกสารที่มีรูปแบบดังกล่าว
  • 🎯 Anchors: ^ และ $ บังคับให้ตรงกับรูปแบบที่กำหนดอย่างแม่นยำ โดยผูกรูปแบบเข้ากับจุดเริ่มต้นและจุดสิ้นสุดของสตริง
  • 🔠 การไม่คำนึงถึงตัวพิมพ์ใหญ่เล็ก: ตัวเลือก $options 'i' จะจับคู่ข้อความโดยไม่คำนึงถึงตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก
  • ตัวคั่นสแลช: ห่อping รูปแบบใน /…/ จะตรงกันโดยไม่ต้องเขียนตัวดำเนินการ $regex
  • 📉 เอกสาร N ฉบับสุดท้าย: รวม sort({_id:-1}) กับ limit(n) เพื่อให้ได้ผลลัพธ์ที่ใหม่ที่สุด
  • 🤖 AI ช่วยเหลือ: ผู้ช่วยจะสร้างรูปแบบ regex และระบุค่าใช้จ่ายด้านประสิทธิภาพในการสแกนคอลเลกชันทั้งหมด

MongoDB นิพจน์ปกติ (Regex)

นิพจน์ปกติ (Regular expressions) ใช้สำหรับการจับคู่รูปแบบ ซึ่งโดยพื้นฐานแล้วคือการค้นหาสตริงภายในเอกสาร

บางครั้งเมื่อดึงเอกสารในคอลเลกชัน คุณอาจไม่ทราบแน่ชัดว่าต้องค้นหาค่าฟิลด์ใด ดังนั้น เราสามารถใช้นิพจน์ทั่วไปเพื่อช่วยในการดึงข้อมูลตามรูปแบบที่ตรงกับค่าการค้นหา

การใช้ตัวดำเนินการ $regex สำหรับการจับคู่รูปแบบ

ตัวดำเนินการ $regex ใน MongoDB ใช้เพื่อค้นหาสตริงที่เจาะจงในคอลเล็กชัน ตัวอย่างต่อไปนี้จะแสดงวิธีดำเนินการนี้

สมมติว่าเรามีชุดข้อมูลพนักงานชุดเดิม ซึ่งมีชื่อฟิลด์ว่า “Employeeid” และ “EmployeeName” และสมมติว่าเรามีเอกสารต่อไปนี้อยู่ในชุดข้อมูลของเรา

รหัสพนักงาน ชื่อพนักงาน
22 นิวมาร์ติน
2 โมฮัน
3 โจ
4 โมฮันอาร์
100 Guru99
6 กูรัง

ในโค้ดด้านล่างนี้ เราใช้ตัวดำเนินการ $regex เพื่อระบุเกณฑ์การค้นหา

การใช้ $regex OperaTor สำหรับการจับคู่รูปแบบ

db.Employee.find({EmployeeName : {$regex: "Gu" }}).forEach(printjson)

Code คำอธิบาย:

  1. ในที่นี้เราต้องการค้นหาชื่อพนักงานทั้งหมดที่มีตัวอักษร 'Gu' อยู่ ดังนั้นเราจึงระบุตัวดำเนินการ $regex เพื่อกำหนดเกณฑ์การค้นหาเป็น 'Gu'
  2. printjson ถูกใช้เพื่อพิมพ์เอกสารแต่ละฉบับที่แบบสอบถามส่งคืนด้วยวิธีที่ดีกว่า

หากดำเนินการคำสั่งสำเร็จ จะแสดงผลลัพธ์ต่อไปนี้:

Output:

การใช้ $regex OperaTor สำหรับการจับคู่รูปแบบ

ผลลัพธ์แสดงให้เห็นอย่างชัดเจนว่าเอกสารเหล่านั้นที่ชื่อพนักงานมีอักขระ 'Gu' จะถูกส่งกลับ

สมมติว่าชุดเอกสารของคุณมีเอกสารดังต่อไปนี้ พร้อมด้วยเอกสารเพิ่มเติมอีกฉบับหนึ่งซึ่งมีชื่อพนักงานระบุว่า “Guru999” หากคุณป้อนเกณฑ์การค้นหาเป็น “Guru99” นอกจากนี้ยังจะส่งคืนเอกสารที่มี “Guru999” แต่สมมติว่าถ้าเราไม่ต้องการแบบนั้นและต้องการส่งคืนเอกสารด้วยหมายเลข “ 999” เท่านั้นGuru99” จากนั้นเราสามารถใช้การจับคู่รูปแบบที่แม่นยำได้ ในการจับคู่รูปแบบที่แม่นยำ เราจะใช้ตัวอักษร ^ และ $ โดยเราจะเพิ่มตัวอักษร ^ ไว้ที่ต้นสตริงและตัวอักษร $ ไว้ที่ท้ายสตริง

รหัสพนักงาน ชื่อพนักงาน
22 นิวมาร์ติน
2 โมฮัน
3 โจ
4 โมฮันอาร์
100 Guru99
6 กูรัง
8 Guru999

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงวิธีดำเนินการนี้

การใช้ $regex OperaTor สำหรับการจับคู่รูปแบบ

db.Employee.find({EmployeeName : {$regex: "^Guru99$"}}).forEach(printjson)

Code คำอธิบาย:

  1. ในเกณฑ์การค้นหานี้ เราใช้เครื่องหมาย ^ และ $ เครื่องหมาย ^ ใช้เพื่อตรวจสอบว่าสตริงเริ่มต้นด้วยอักขระที่กำหนด และเครื่องหมาย $ ใช้เพื่อตรวจสอบว่าสตริงลงท้ายด้วยอักขระที่กำหนด ดังนั้นเมื่อโค้ดทำงาน มันจะดึงเฉพาะสตริงที่มีชื่อว่า “Guru99. "
  2. printjson ถูกใช้เพื่อพิมพ์เอกสารแต่ละฉบับที่แบบสอบถามส่งคืนด้วยวิธีที่ดีกว่า

หากดำเนินการคำสั่งสำเร็จ จะแสดงผลลัพธ์ต่อไปนี้:

Output:

การใช้ $regex OperaTor สำหรับการจับคู่รูปแบบ

จากผลลัพธ์ จะเห็นได้อย่างชัดเจนว่าสตริง “Guruได้รับ "99" แล้ว

การจับคู่รูปแบบด้วยตัวเลือก $

เมื่อใช้ตัวดำเนินการ $regex คุณยังสามารถระบุตัวเลือกเพิ่มเติมได้โดยใช้ $ตัวเลือก คำสำคัญ. ตัวอย่างเช่น สมมติว่าคุณต้องการค้นหาเอกสารทั้งหมดที่มี 'Gu' อยู่ในชื่อพนักงาน โดยไม่คำนึงว่าจะคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่หรือไม่ก็ตาม หากต้องการผลลัพธ์ดังกล่าว เราจำเป็นต้องใช้ $ตัวเลือก โดยใช้พารามิเตอร์ที่ไม่คำนึงถึงตัวพิมพ์ใหญ่เล็ก

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงวิธีดำเนินการนี้

สมมติว่าเรามีชุดข้อมูลพนักงานชุดเดิม ซึ่งมีชื่อฟิลด์ว่า “Employeeid” และ “EmployeeName”

สมมติว่าเรามีเอกสารต่อไปนี้อยู่ในคลังเอกสารของเรา

รหัสพนักงาน ชื่อพนักงาน
22 นิวมาร์ติน
2 โมฮัน
3 โจ
4 โมฮันอาร์
100 Guru99
6 กูรัง
7 กูรู99

หากเราเรียกใช้คำสั่งค้นหาเดียวกันกับในหัวข้อที่แล้ว เราจะไม่พบเอกสารที่มีคำว่า “GURU99” ในผลลัพธ์ เพื่อให้แน่ใจว่าเอกสารนี้จะปรากฏในชุดผลลัพธ์ เราต้องเพิ่มพารามิเตอร์ “i” ในตัวแปร $options

การจับคู่รูปแบบด้วยตัวเลือก $

db.Employee.find({EmployeeName:{$regex: "Gu",$options:'i'}}).forEach(printjson)

Code คำอธิบาย:

  1. ตัวเลือก $options ที่มีพารามิเตอร์ 'i' (ซึ่งหมายถึงการไม่คำนึงถึงตัวพิมพ์ใหญ่หรือเล็ก) ระบุว่าเราต้องการทำการค้นหาไม่ว่าเราจะพบตัวอักษร 'Gu' ในตัวพิมพ์เล็กหรือตัวพิมพ์ใหญ่ก็ตาม

หากดำเนินการคำสั่งสำเร็จ จะแสดงผลลัพธ์ต่อไปนี้:

Output:

การจับคู่รูปแบบด้วยตัวเลือก $

  1. ผลลัพธ์แสดงให้เห็นอย่างชัดเจนว่า แม้ว่าเอกสารฉบับหนึ่งจะมีตัวอักษรพิมพ์ใหญ่ 'Gu' แต่เอกสารนั้นก็ยังคงแสดงอยู่ในชุดผลลัพธ์

การจับคู่รูปแบบโดยไม่ใช้ตัวดำเนินการ regex

เราสามารถทำการจับคู่รูปแบบได้โดยไม่ต้องใช้ตัวดำเนินการ $regex ตัวอย่างต่อไปนี้แสดงวิธีการทำเช่นนั้น

การจับคู่รูปแบบโดยไม่มี Regex OperaTor

db.Employee.find({EmployeeName: /Gu/}).forEach(printjson)

Code คำอธิบาย:

  1. ตัวคั่น “//” โดยพื้นฐานแล้วหมายถึงการระบุเกณฑ์การค้นหาภายในตัวคั่นเหล่านี้ ดังนั้น เราจึงระบุ /Gu/ เพื่อค้นหาเอกสารที่มีคำว่า 'Gu' อยู่ในชื่อพนักงานอีกครั้ง

หากดำเนินการคำสั่งสำเร็จ จะแสดงผลลัพธ์ต่อไปนี้:

Output:

การจับคู่รูปแบบโดยไม่มี Regex OperaTor

ผลลัพธ์แสดงให้เห็นอย่างชัดเจนว่าเอกสารเหล่านั้นที่ชื่อพนักงานมีอักขระ 'Gu' จะถูกส่งกลับ

กำลังดึงเอกสาร 'n' สุดท้ายจากคอลเล็กชัน

มีหลายวิธีในการรับเอกสาร n สุดท้ายในคอลเล็กชัน

เรามาดูวิธีการหนึ่งโดยทำตามขั้นตอนต่อไปนี้กัน

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงวิธีดำเนินการนี้

สมมติว่าเรามีชุดข้อมูลพนักงานชุดเดิม ซึ่งมีชื่อฟิลด์ว่า “Employeeid” และ “EmployeeName”

สมมติว่าเรามีเอกสารต่อไปนี้อยู่ในคลังเอกสารของเรา:

รหัสพนักงาน ชื่อพนักงาน
22 นิวมาร์ติน
2 โมฮัน
3 โจ
4 โมฮันอาร์
100 Guru99
6 กูรัง
7 กูรู99

กำลังดึงเอกสาร n รายการสุดท้ายจากคอลเลกชัน

db.Employee.find().sort({_id:-1}).limit(2).forEach(printjson)

Code คำอธิบาย:

  1. เมื่อค้นหาเอกสาร ให้ใช้ฟังก์ชัน sort เพื่อเรียงลำดับระเบียนจากมากไปน้อยโดยอิงจากค่าฟิลด์ _id ในชุดข้อมูล ค่า -1 โดยทั่วไปหมายถึงการเรียงลำดับเอกสารจากมากไปน้อย เพื่อให้เอกสารสุดท้ายกลายเป็นเอกสารแรกที่แสดงผล
  2. จากนั้นใช้เงื่อนไข limit เพื่อแสดงเฉพาะจำนวนระเบียนที่คุณต้องการ ในที่นี้เราได้ตั้งค่าเงื่อนไข limit (2) ดังนั้นจะดึงเอกสารสองรายการสุดท้าย

หากดำเนินการคำสั่งสำเร็จ จะแสดงผลลัพธ์ต่อไปนี้:

Output:

กำลังดึงเอกสาร n รายการสุดท้ายจากคอลเลกชัน

ผลลัพธ์จะแสดงอย่างชัดเจนว่าเอกสารสองฉบับสุดท้ายในคอลเล็กชันถูกแสดง ดังนั้น เราได้แสดงอย่างชัดเจนแล้วว่าในการดึงเอกสาร 'n' ฉบับสุดท้ายในคอลเล็กชัน ก่อนอื่นเราต้องเรียงลำดับเอกสารจากมากไปน้อย จากนั้นจึงใช้คำสั่งจำกัดเพื่อส่งคืนเอกสาร 'n' ฉบับที่ต้องการ

หมายเหตุ: หากทำการค้นหาในสตริงที่มีความยาวมากกว่า 38,000 ตัวอักษร จะไม่แสดงผลลัพธ์ที่ถูกต้อง

คำถามที่พบบ่อย

Anchor รูปแบบที่มี ^ และ $ รูปแบบ “^Guru“ราคา 99 ดอลลาร์” ตรงกับเฉพาะ “Guru99” และปฏิเสธ “Guru999” เพราะ ^ ผูกจุดเริ่มต้นของสตริง และ $ ผูกจุดสิ้นสุด

เฉพาะรูปแบบที่คำนึงถึงตัวพิมพ์ใหญ่และตัวพิมพ์เล็กที่มีคำนำหน้า ^ เท่านั้นที่จะใช้ดัชนีได้อย่างมีประสิทธิภาพ รูปแบบที่ไม่ยึดตรึงหรือรูปแบบที่ไม่คำนึงถึงตัวพิมพ์ใหญ่และตัวพิมพ์เล็กจะทำให้เกิดการสแกนคอลเลกชันทั้งหมด ดังนั้นควรยึดตรึงคำนำหน้าทุกครั้งที่เป็นไปได้

นำหน้าอักขระพิเศษ เช่น จุด เครื่องหมายดอกจัน เครื่องหมายบวก หรือวงเล็บด้วยเครื่องหมายแบ็กสแลช ตัวอย่างเช่น รูปแบบสำหรับนามสกุลไฟล์ “.com” จะทำการหลีกเลี่ยงเครื่องหมายจุด เพื่อไม่ให้ถูกมองว่าเป็นอักขระใดๆ

$regex สามารถจับคู่รูปแบบได้อย่างยืดหยุ่นในฟิลด์เดียว และสามารถสแกนทั้งคอลเลกชันได้ ส่วน $text ใช้ดัชนีข้อความสำหรับการค้นหาคำอย่างรวดเร็วในฟิลด์ที่มีดัชนี แต่ไม่รองรับรูปแบบสตริงย่อยบางส่วน

ใช่แล้ว เมื่อสตริงที่ค้นหามีความยาวเกินประมาณ 38,000 ตัวอักษร การค้นหาอาจไม่ให้ผลลัพธ์ที่ถูกต้อง ควรใช้รูปแบบและฟิลด์เป้าหมายภายในขีดจำกัดนี้เพื่อให้ได้ผลลัพธ์ที่เชื่อถือได้

จัดเก็บสำเนาของฟิลด์ในรูปแบบตัวพิมพ์เล็กสำหรับการค้นหาแบบไม่คำนึงถึงตัวพิมพ์ใหญ่-เล็ก ยึดรูปแบบด้วย ^ และเลือกใช้ดัชนีข้อความหรือการค้นหา Atlas ในคอลเลกชันขนาดใหญ่แทนการใช้ $regex ที่ไม่มีจุดยึด

ผู้ช่วย AI จะแปลงกฎภาษาอังกฤษธรรมดาให้เป็นรูปแบบ $regex เพิ่มจุดยึดและแฟล็ก $options ที่ถูกต้อง และแจ้งเตือนเมื่อการค้นหาจะทำให้เกิดการสแกนคอลเลกชันทั้งหมดที่ช้าลง

ใช่แล้ว AI Copilot จะเขียนรูปแบบที่ไม่ยึดติดใหม่ แนะนำดัชนีข้อความหรือการค้นหา Atlas และแปลง regex ที่ไม่คำนึงถึงตัวพิมพ์ใหญ่เล็กให้เป็นการค้นหาฟิลด์แบบตัวพิมพ์เล็กเพื่อเพิ่มความเร็ว

สรุปโพสต์นี้ด้วย: