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.