Pergunta

I am trying to perform a regex query using pymongo against a mongodb server. The document structure is as follows

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

I want to get all the files that match the pattern *File. I tried doing this as such

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

Yet i get nothing back , am i missing something because according to the mongodb docs this should be possible. If I perform the query in the mongo console it works fine , does this mean the api doesnt support it or am I just using it incorrectly

Foi útil?

Solução 2

Turns out regex searches are done a little differently in pymongo but is just as easy.

Regex is done as follows :

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

This will match all documents that have a files property that has a item within that starts with File

Outras dicas

If you want to include regular expression options (such as ignore case), try this:

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

To avoid the double compilation you can use the bson regex wrapper that comes with PyMongo:

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

Regex just stores the string without trying to compile it, so find_one can then detect the argument as a 'Regex' type and form the appropriate Mongo query.

I feel this way is slightly more Pythonic than the other top answer, e.g.:

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

It's worth reading up on the bson Regex documentation if you plan to use regex queries because there are some caveats.

The solution of re doesn't use the index at all. You should use commands like:

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

( I cannot comment below their replies, so I reply here )

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)

Escaping the pattern before compiling handles all characters.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top