Esecuzione di query regex con pymongo


129

Sto cercando di eseguire una query regex utilizzando pymongo su un server mongodb. La struttura del documento è la seguente

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

Voglio ottenere tutti i file che corrispondono allo schema * File. Ho provato a farlo come tale

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

Eppure non ottengo nulla indietro, mi sto perdendo qualcosa perché secondo i documenti mongodb questo dovrebbe essere possibile. Se eseguo la query nella console di mongo funziona bene, significa che l'API non la supporta o la sto usando in modo errato

Risposte:


191

Se vuoi includere opzioni di espressioni regolari (come ignora maiuscole e minuscole), prova questo:

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

8
Nota anche che regex ancorato all'inizio (cioè: a partire da ^) è in grado di usare gli indici nel db e funzionerà molto più velocemente in quel caso.
drevicko,

1
Il Regex che inizia con ^ può usare un indice solo in alcuni casi . Quando utilizzo re.IGNORECASE credo che mongo non possa usare un indice per eseguire la query.
nonagon

Questo utilizzo è documentato da qualche parte? Non riesco a trovarlo nel documento ufficiale dell'API pymongo.
Hieu,

153

Si scopre che le ricerche regex sono fatte in modo leggermente diverso in pymongo ma è altrettanto facile.

Regex viene eseguito come segue:

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

Ciò corrisponderà a tutti i documenti che hanno una proprietà files che contiene un elemento che inizia con File


9
In realtà, quello che hai qui è anche il modo in cui viene fatto in javascript (e probabilmente anche in altre lingue) se lo usi $regex. La risposta di Eric è il modo in cui il pitone è un po 'diverso.
drevicko,

qual è la differenza? Usano entrambi python pymongo correttamente? Fa parte delle query mongodb, quindi non vedo davvero il problema.
Dexter,

10
Ignorecase è possibile in regex di mongodb JScript anche. db.collectionname.find ({'files': {'$ regex': '^ File', '$ options': 'i'}})
Ajay Gupta

5
Questa risposta mi sembra migliore. Perché preoccuparsi di compilare un Python RE se lo vuoi solo stringere in modo che Mongo possa compilarlo di nuovo? L' $regexoperatore di Mongo prende una $optionsdiscussione.
Mark E. Haase,

3
Si prega di utilizzare r'^File'invece di '^File'evitare altri problemi
Aminah Nuraini,

9

Per evitare la doppia compilazione è possibile utilizzare il wrapper bson regex fornito con PyMongo:

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

Regex memorizza semplicemente la stringa senza provare a compilarla, così find_one può quindi rilevare l'argomento come un tipo 'Regex' e formare la query Mongo appropriata.

Ritengo che in questo modo sia leggermente più Pythonic rispetto all'altra risposta principale, ad esempio:

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

Vale la pena leggere la documentazione di Regson suson se si prevede di utilizzare le query regex perché ci sono alcuni avvertimenti.


1
Se devi abbinare nuovamente un array usando $ in allora $ regex non funzionerebbe per te. bson.regex.Regex farà il trucco!
odedfos,

4

La soluzione di renon usa affatto l'indice. Dovresti usare comandi come:

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

(Non posso commentare sotto le loro risposte, quindi rispondo qui)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.