Агрегация в mongoengine возвращает $ geoNear, действительна только как первый этап конвейера

#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. Итак, где эта документация?

4. docs.mongoengine.org/guide/querying.html#aggregation

Ответ №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)))