Melakukan Permintaan regex dengan pymongo

129

Saya mencoba untuk melakukan permintaan regex menggunakan pymongo terhadap server mongodb. Struktur dokumen adalah sebagai berikut

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

Saya ingin mendapatkan semua file yang cocok dengan pola * File. Saya mencoba melakukan ini seperti itu

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

Namun saya tidak mendapatkan apa-apa kembali, apakah saya kehilangan sesuatu karena menurut mongodb docs ini harus mungkin. Jika saya melakukan kueri di konsol mongo itu berfungsi dengan baik, apakah ini berarti api tidak mendukungnya atau saya hanya menggunakannya dengan salah

RC1140
sumber

Jawaban:

191

Jika Anda ingin menyertakan opsi ekspresi reguler (seperti abaikan huruf besar-kecil), coba ini:

import re
regx = re.compile("^foo", re.IGNORECASE)
db.users.find_one({"files": regx})
Eric
sumber
8
Perhatikan juga bahwa regex yang dilabuhkan di awal (yaitu: dimulai dengan ^) dapat menggunakan indeks di db, dan akan berjalan jauh lebih cepat dalam kasus itu.
drevicko
1
Dimulai dengan Regex ^ hanya dapat menggunakan indeks dalam kasus tertentu . Saat menggunakan re.IGNORECASE, saya yakin mongo tidak bisa menggunakan indeks untuk melakukan kueri.
nonagon
Apakah penggunaan ini didokumentasikan di suatu tempat? Saya tidak dapat menemukan ini di doc API pymongo resmi.
Hieu
153

Ternyata pencarian regex dilakukan sedikit berbeda di pymongo tetapi sama mudahnya.

Regex dilakukan sebagai berikut:

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

Ini akan cocok dengan semua dokumen yang memiliki properti file yang memiliki item di dalamnya yang dimulai dengan File

RC1140
sumber
9
Sebenarnya, apa yang Anda miliki di sini juga merupakan cara melakukannya dalam javascript (dan mungkin bahasa lain juga) jika Anda menggunakannya $regex. @ Jawaban Eric adalah cara python yang sedikit berbeda.
drevicko
apa bedanya? Mereka berdua menggunakan python pymongo yang benar? Ini adalah bagian dari pertanyaan mongodb jadi saya tidak melihat masalah sebenarnya.
Dexter
10
Ignorecase dimungkinkan dalam regex mongodb JScript juga yaitu. db.collectionname.find ({'files': {'$ regex': '^ File', '$ options': 'i'}})
Ajay Gupta
5
Jawaban ini terlihat lebih baik di mata saya. Mengapa repot-repot menyusun RE Python jika Anda hanya akan mengencangkannya sehingga Mongo dapat mengkompilasinya lagi? Operator Mongo $regexmengambil $optionsargumen.
Mark E. Haase
3
Silakan gunakan r'^File'alih-alih '^File'menghindari masalah lain
Aminah Nuraini
9

Untuk menghindari kompilasi ganda Anda dapat menggunakan pembungkus bson regex yang disertakan dengan PyMongo:

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

Regex hanya menyimpan string tanpa mencoba mengompilasinya, jadi find_one kemudian dapat mendeteksi argumen sebagai tipe 'Regex' dan membentuk kueri Mongo yang sesuai.

Saya merasa cara ini sedikit lebih Pythonic daripada jawaban teratas lainnya, misalnya:

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

Ada baiknya membaca di dokumentasi bson Regex jika Anda berencana untuk menggunakan permintaan regex karena ada beberapa peringatan.

Keeely
sumber
1
Jika Anda perlu mencocokkan array dengan menggunakan $ maka $ regex tidak akan bekerja untuk Anda. bson.regex.Regex akan melakukan trik!
odedfos
4

Solusi retidak menggunakan indeks sama sekali. Anda harus menggunakan perintah seperti:

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

(Saya tidak bisa berkomentar di bawah balasan mereka, jadi saya balas di sini)

Jeff
sumber