Wykonywanie zapytań regex za pomocą pymongo

Próbuję wykonać zapytanie regex używając pymongo przeciwko serwerowi mongodb. Struktura dokumentu jest następująca

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

Chcę uzyskać wszystkie pliki pasujące do pliku wzorca*. Próbowałem zrobić to jako takie

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

A jednak nic nie odzyskuję, czy coś mi umyka, bo według dokumentów mongodb powinno to być możliwe. Jeśli wykonam zapytanie w konsoli mongo to działa dobrze, czy to oznacza, że api nie obsługuje go lub po prostu używam go nieprawidłowo

Author: RC1140, 2010-08-14

5 answers

Jeśli chcesz dodać opcje wyrażenia regularnego (np. ignoruj wielkość liter), spróbuj tak:

import re
regx = re.compile("^foo", re.IGNORECASE)
db.users.find_one({"files": regx})
 155
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-18 06:56:28

Okazuje się, że wyszukiwanie regex odbywa się trochę inaczej w pymongo, ale jest równie łatwe.

Regex jest wykonywany w następujący sposób:

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

To dopasuje wszystkie dokumenty, które mają właściwość files, w której znajduje się element zaczynający się od File

 125
Author: RC1140,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-14 13:02:17

Aby uniknąć podwójnej kompilacji, możesz użyć wrappera regex BSON, który jest dołączony do PyMongo:

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

Regex przechowuje łańcuch znaków bez próby kompilacji, więc find_one może wykryć argument jako typ 'Regex' i utworzyć odpowiednie zapytanie Mongo.

Wydaje mi się, że ten sposób jest nieco bardziej Pythoniczny niż inne topowe odpowiedzi, np.:

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

Warto zapoznać się z dokumentacją Regex bson, jeśli planujesz użyć zapytań regex, ponieważ istnieją pewne zastrzeżenia.

 1
Author: Keeely,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-23 10:51:20
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)

Wyjście z wzorca przed kompilacją obsługuje wszystkie znaki.

 0
Author: daemon24,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-17 17:12:43

Rozwiązanie re w ogóle nie używa indeksu. Powinieneś używać poleceń takich jak:

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

(nie mogę komentować poniżej ich odpowiedzi, więc odpowiadam tutaj)

 0
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-16 07:44:41