#python-3.x #mongodb #pymongo #mongoengine
#python-3.x #mongodb #pymongo #mongoengine
Вопрос:
Я пытаюсь использовать $ geoNear в конвейере агрегации.
Запуск его из оболочки mongo также работает нормально:
db.base_model.aggregate([{$geoNear: {near: {type: "Point", coordinates: [10.634584, 35.8245029]}, distanceField: "coordinates"}}])
.
Но запуск с использованием mongoengine следующим образом
model.objects.aggregate(*[{"$geoNear": {"near": {"type": "Point", "coordinates": [10.634584, 35.8245029]}, "distanceField": "coordinates"}}])
возвращает следующую ошибку $ geoNear допустимо только как первый этап конвейера, даже если $ geoNear является ЕДИНСТВЕННЫМ этапом конвейера. Есть идеи, почему это происходит?
Использование:
- mongoengine: 0.17.0
- Версия сервера MongoDB: 4.4.0
Комментарии:
1. Скорее всего, вы неправильно используете mongoengine, менее вероятно, что он это не поддерживает. Найдите соответствующую документацию, убедитесь, что вы следуете ей, добавьте к вопросу.
2. Для этого нет официальной документации. Все остальные этапы, такие как $match и $project, работают нормально, за исключением $ geoNear. В официальной документации Mongoengine говорится, что «MongoEngine предоставляет оболочку вокруг встроенных методов и предоставляет некоторые свои собственные, которые реализованы в виде кода Javascript, который выполняется на сервере базы данных».
3. Итак, где эта документация?
Ответ №1:
Как объясняется в билете на github, MongoEngine фактически добавляет этап в конвейер, если у вас есть пропуск / ограничение / сортировка или фильтр, определенный в вашем наборе запросов. Вероятно, это то, что в вашем случае сталкивается
Ответ №2:
Рабочий пример $ geoNear, который работает в mongoengine.
from mongoengine import *
connect()
class Aggr(Document):
name = StringField()
c = PointField()
Aggr(name='X', c=[10.634584, 35.8245029]).save()
Aggr(name='Y', c=[10.634584, 35.8245029]).save()
pipeline = [
{"$geoNear": {
"near": {"type": "Point", "coordinates": [10.634584, 35.8245029]}, "distanceField": "c",
"spherical": True
}}
]
print(list(Aggr.objects.aggregate(*pipeline)))