J'essaye de faire une requête regex en utilisant pymongo contre un serveur mongodb. La structure du document est la suivante
{
"files": [
"File 1",
"File 2",
"File 3",
"File 4"
],
"rootFolder": "/Location/Of/Files"
}
Je veux obtenir tous les fichiers qui correspondent au modèle * Fichier. J'ai essayé de le faire en tant que tel
db.collectionName.find({'files':'/^File/'})
Pourtant, je ne reçois rien en retour, quelque chose me manque, car, selon la documentation de mongodb, cela devrait être possible. Si j'exécute la requête dans la console Mongo, cela fonctionne bien. Cela signifie-t-il que l'API ne la prend pas en charge ou est-ce que je ne l'utilise pas correctement?
Il s'avère que les recherches sur les expressions rationnelles se font un peu différemment dans pymongo mais sont tout aussi faciles.
La regex se fait comme suit:
db.collectionname.find({'files':{'$regex':'^File'}})
Cela correspond à tous les documents ayant une propriété files ayant un élément commençant par File.
Si vous souhaitez inclure des options d’expression régulière (comme ignorer la casse), essayez ceci:
import re
regx = re.compile("^foo", re.IGNORECASE)
db.users.find_one({"files": regx})
Pour éviter la double compilation, vous pouvez utiliser le wrapper bson regex fourni avec PyMongo:
>>> regx = bson.regex.Regex('^foo')
>>> db.users.find_one({"files": regx})
Regex stocke simplement la chaîne sans essayer de la compiler. Ainsi, find_one peut alors détecter l'argument en tant que type 'Regex' et former la requête Mongo appropriée.
Je pense que cette méthode est légèrement plus pythonique que l’autre grande réponse, par exemple:
>>> db.collectionname.find({'files':{'$regex':'^File'}})
Il vaut la peine de lire la documentation de bson Regex si vous envisagez d’utiliser des requêtes regex, car il y a certaines réserves.
La solution de re
n’utilise pas du tout l’index. Vous devriez utiliser des commandes telles que:
db.collectionname.find({'files':{'$regex':'^File'}})
(Je ne peux pas commenter ci-dessous leurs réponses, alors je réponds ici)
import re
def get_pattern_query(pattern,starting_with=False,ending_with=False,ignore_case=False):
start = '^' if starting_with else '.*'
end = '$' if ending_with else '.*'
pattern = start + re.escape(pattern) + end
return re.compile(pattern, re.IGNORECASE) if ignore_case else re.compile(pattern)
Échappe au motif avant de compiler, gère tous les caractères.