ดำเนินการสืบค้น regex ด้วย pymongo


129

ฉันกำลังพยายามค้นหา regex โดยใช้ pymongo กับเซิร์ฟเวอร์ mongodb โครงสร้างเอกสารมีดังนี้

{
  "files": [
    "File 1",
    "File 2",
    "File 3",
    "File 4"
  ],
  "rootFolder": "/Location/Of/Files"
}

ฉันต้องการรับไฟล์ทั้งหมดที่ตรงกับรูปแบบ * ไฟล์ ฉันลองทำสิ่งนี้แล้ว

db.collectionName.find({'files':'/^File/'})

แต่ฉันไม่ได้อะไรกลับมาฉันขาดอะไรไปเพราะตามเอกสารของ mongodb สิ่งนี้น่าจะทำได้ หากฉันทำการค้นหาในคอนโซล mongo มันใช้งานได้ดีหมายความว่า api ไม่รองรับหรือฉันแค่ใช้มันไม่ถูกต้อง

คำตอบ:


191

หากคุณต้องการรวมตัวเลือกนิพจน์ทั่วไป (เช่นละเว้นตัวพิมพ์เล็กและใหญ่) ให้ลองทำดังนี้:

import re
regx = re.compile("^foo", re.IGNORECASE)
db.users.find_one({"files": regx})

8
โปรดทราบด้วยว่า regex ที่ยึดไว้ที่จุดเริ่มต้น (เช่น: เริ่มต้นด้วย^) สามารถใช้ดัชนีในฐานข้อมูลได้และจะทำงานได้เร็วขึ้นมากในกรณีนั้น
drevicko

1
Regex เริ่มต้นด้วย ^ สามารถใช้ดัชนีได้ในบางกรณีเท่านั้น เมื่อใช้ re.IGNORECASE ฉันเชื่อว่า mongo ไม่สามารถใช้ดัชนีเพื่อดำเนินการค้นหาได้
nonagon

การใช้งานนี้ได้รับการบันทึกไว้ที่ใดที่หนึ่งหรือไม่? ฉันไม่พบสิ่งนี้ในเอกสาร pymongo API อย่างเป็นทางการ
Hieu

153

ปรากฎว่าการค้นหา regex นั้นแตกต่างกันเล็กน้อยใน pymongo แต่ก็ง่ายเหมือนกัน

Regex ทำได้ดังนี้:

db.collectionname.find({'files':{'$regex':'^File'}})

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


9
จริงๆแล้วสิ่งที่คุณได้ที่นี่ยังเป็นวิธีที่จะทำใน JavaScript (และอาจภาษาอื่น ๆ ด้วย) $regexถ้าคุณใช้ คำตอบของ @ Eric คือวิธีหลามที่แตกต่างกันเล็กน้อย
drevicko

อะไรคือความแตกต่าง? ทั้งคู่ใช้ python pymongo ถูกต้องหรือไม่? เป็นส่วนหนึ่งของแบบสอบถาม mongodb ดังนั้นฉันจึงไม่เห็นปัญหาจริงๆ
Dexter

10
Ignorecase เป็นไปได้ใน regex ของ mongodb JScript เช่นกัน db.collectionname.find ({'files': {'$ regex': '^ File', '$ options': 'i'}})
Ajay Gupta

5
คำตอบนี้ดูดีกว่าในสายตาของฉัน ทำไมต้องกังวลกับการรวบรวม Python RE ถ้าคุณแค่จะทำให้มันรัดกุมเพื่อให้ Mongo สามารถรวบรวมได้อีกครั้ง $regexตัวดำเนินการMongo $optionsโต้แย้ง
Mark E. Haase

3
โปรดใช้r'^File'แทน'^File'เพื่อหลีกเลี่ยงปัญหาอื่น ๆ
Aminah Nuraini

9

เพื่อหลีกเลี่ยงการคอมไพล์ซ้ำคุณสามารถใช้ bson regex wrapper ที่มาพร้อมกับ PyMongo:

>>> regx = bson.regex.Regex('^foo')
>>> db.users.find_one({"files": regx})

Regex จัดเก็บสตริงโดยไม่ต้องพยายามรวบรวมดังนั้น find_one จึงสามารถตรวจจับอาร์กิวเมนต์เป็นประเภท 'Regex' และสร้างแบบสอบถาม Mongo ที่เหมาะสม

ฉันรู้สึกว่าวิธีนี้ Pythonic มากกว่าคำตอบอื่น ๆ เล็กน้อยเช่น:

>>> db.collectionname.find({'files':{'$regex':'^File'}})

ควรอ่านเอกสาร bson Regex หากคุณวางแผนที่จะใช้การสืบค้น regex เนื่องจากมีข้อแม้บางประการ


1
หากคุณต้องการจับคู่อาร์เรย์อีกครั้งโดยใช้ $ ใน $ regex จะไม่เหมาะกับคุณ bson.regex.Regex จะทำเคล็ดลับ!
odedfos

4

การแก้ปัญหาreไม่ใช้ดัชนีเลย คุณควรใช้คำสั่งเช่น:

db.collectionname.find({'files':{'$regex':'^File'}})

(ฉันไม่สามารถแสดงความคิดเห็นด้านล่างคำตอบของพวกเขาดังนั้นฉันจึงตอบกลับที่นี่)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.