Executando consultas regex com pymongo


129

Estou tentando executar uma consulta regex usando o pymongo em um servidor mongodb. A estrutura do documento é a seguinte

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

Quero obter todos os arquivos que correspondam ao padrão * Arquivo. Eu tentei fazer isso como tal

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

No entanto, não recebo nada de volta, estou perdendo alguma coisa porque, de acordo com os documentos do mongodb, isso deve ser possível. Se eu executar a consulta no console mongo, ela funciona bem, isso significa que a API não a suporta ou eu estou apenas usando incorretamente

Respostas:


191

Se você deseja incluir opções de expressão regular (como ignorar maiúsculas e minúsculas), tente o seguinte:

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

8
Observe também que os regexs ancorados no início (ou seja: começando com ^) são capazes de usar índices no banco de dados e, nesse caso, serão executados muito mais rapidamente.
precisa saber é o seguinte

1
Regex começando com ^ só pode usar um índice em certos casos . Ao usar re.IGNORECASE, acredito que o mongo não pode usar um índice para realizar a consulta.
Nonagon 8/04

Esse uso está documentado em algum lugar? Não consigo encontrar isso no documento oficial da API do pymongo.
197

153

Acontece que as pesquisas regex são feitas de maneira um pouco diferente no pymongo, mas é igualmente fácil.

Regex é feito da seguinte maneira:

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

Isso corresponderá a todos os documentos que possuem uma propriedade de arquivos que possui um item que começa com Arquivo


9
Na verdade, o que você tem aqui também é como é feito em javascript (e provavelmente em outros idiomas também) se você usar $regex. A resposta de Eric é a maneira python que é um pouco diferente.
drevicko

qual é a diferença? Ambos estão usando python pymongo correto? É parte das consultas do mongodb, então não vejo o problema realmente.
Dexter

10
Ignorecase é possível no regex do mongodb JScript também viz. db.collectionname.find ({'files': {'$ regex': '^ File', '$ options': 'i'}}) ''
Ajay Gupta

5
Esta resposta parece melhor aos meus olhos. Por que se incomodar em compilar um Python RE se você apenas o especificar, para que o Mongo possa compilá-lo novamente? O $regexoperador do Mongo aceita uma $optionsdiscussão.
Mark E. Haase

3
Utilize r'^File'em vez de '^File'evitar outro problema
Aminah Nuraini

9

Para evitar a compilação dupla, você pode usar o wrapper bson regex que acompanha o PyMongo:

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

O Regex apenas armazena a string sem tentar compilá-la, portanto, find_one pode detectar o argumento como um tipo 'Regex' e formar a consulta Mongo apropriada.

Eu sinto que esse caminho é um pouco mais pitônico do que a outra resposta principal, por exemplo:

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

Vale a pena ler na documentação do bson Regex se você planeja usar consultas regex porque existem algumas ressalvas.


1
Se você precisar corresponder novamente a uma matriz usando $ in, $ regex não funcionaria para você. bson.regex.Regex vai fazer o truque!
Odedfos 4/07

4

A solução de renão usa o índice. Você deve usar comandos como:

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

(Não posso comentar abaixo das respostas deles, por isso respondo aqui)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.