#python #mongodb #pymongo
#python #mongodb #pymongo
Вопрос:
Я пытаюсь выполнить запрос, который создается с использованием строковой переменной, но, как ни странно, я не получаю результатов только при использовании переменной. Я думаю, что это может быть ошибка в пакете pymongo, но я хочу убедиться, что я ничего не упустил.
Я использую pymongo версии v3.11.2, mongo server версии 4.4 и python версии v3.9.
Этот запрос не возвращает результатов и завершается немедленно без ошибок:
keyword = 'some text'
results = db.myCollection.aggregate([
{
'$match': {
'$text': {
'$search': keyword # string stored as variable
}
}
}
])
Хотя этот запрос возвращает ожидаемые результаты после некоторого времени вычисления запроса:
results = db.myCollection.aggregate([
{
'$match': {
'$text': {
'$search': 'some text' # bare string instead of variable
}
}
}
])
Я получаю похожие проблемы на шаге $ regexFindAll. У меня нет никаких проблем при использовании переменной на этапе проектирования.
Я ожидаю, что это будет распространенный вариант использования. Например, серверная часть python принимает вводимые пользователем данные и возвращает соответствующие результаты поиска.
Я попытался преобразовать переменную в строку, закодировать ее и создать запрос в другом месте, но безуспешно.
Комментарии:
1.
$text
и$regexFindAll
оба они просто уступают MongoDB Atlas Search, который использует Lucene. Вы должны проверить это, потому что вы получите гораздо лучшие результаты и производительность. Есть свободный уровень: docs.atlas.mongodb.com/reference/atlas-search/tutorial
Ответ №1:
Невозможно воспроизвести. Приведенный ниже сценарий bash (требуется docker) эмулирует ваш код в точной задокументированной среде, и значения правильно возвращаются с использованием аргумента переменной.
PROJECT_NAME=text_search
MONGODB_VERSION=4.4
PYTHON_VERSION=3.9
PYMONGO_VERSION=3.11.2
docker network create local_temp 2> /dev/null
docker run --rm --network local_temp -d --name mongodb_temp mongo:${MONGODB_VERSION}
cd "$(mktemp -d)" || exit
cat << EOF > requirements.txt
pymongo==${PYMONGO_VERSION}
EOF
cat << 'EOF' > ${PROJECT_NAME}.py
from pymongo import MongoClient, TEXT
db = MongoClient('mongodb://mongodb_temp')['mydatabase']
db.myCollection.create_index([('file_name', TEXT)])
db.myCollection.replace_one({'_id': 1}, {'_id': 1, "file_name": "Contains some text we are searching"}, upsert=True)
keyword = 'some text'
cursor = db.myCollection.aggregate([
{'$match': {'$text': {'$search': keyword}}},
{'$project': {'file_name': 1}}])
for item in cursor:
print(item)
EOF
cat << EOF > Dockerfile
FROM python:${PYTHON_VERSION}
COPY ./* /
RUN pip install -r /requirements.txt
CMD ["python", "${PROJECT_NAME}.py"]
EOF
docker build --tag ${PROJECT_NAME}:latest .
docker run --rm --network local_temp --name ${PROJECT_NAME} ${PROJECT_NAME}:latest
docker stop "$(docker ps -a -q --filter name=mongodb_temp)" > /dev/null
docker image rm ${PROJECT_NAME}:latest > /dev/null
docker network rm local_temp > /dev/null
С принтами:
{'_id': 1, 'file_name': 'Contains some text we are searching'}
Комментарии:
1. Я также выполнял свои запросы в записной книжке jupyter. Не уверен, в чем дело, но запуск точно такого же кода на следующий день работал так, как ожидалось. Должно быть, была какая-то проблема с моим запущенным ядром.