Запрос агрегации Flask-MongoEngine & PyMongo

Я пытаюсь выполнить запрос агрегации с помощью flask-mongoengine, и из того, что я прочитал, это не похоже на то, что это возможно.

Я просмотрел несколько тем форума, цепочек электронной почты и несколько вопросов о переполнении стека, но я не нашел действительно хороший пример того, как реализовать агрегацию с помощью flask-mongoengine.

В этом вопросе есть комментарий, в котором говорится, что вы должны использовать "сырые функции pymongo и агрегации". Однако нет примеров того, как это может работать. Я переработал Python и получил базовое приложение с использованием флеш-фреймворка, но вникание в полноценные приложения и подключение/запрос к Mongo для меня довольно новы.

Может ли кто-нибудь предоставить пример (или ссылку на пример) того, как я могу использовать мои модели flask-mongoengine, но запрос с использованием структуры агрегации с PyMongo? Будет ли это требовать двух соединений с MongoDB (один для PyMongo для выполнения запроса на агрегацию, а второй для обычного запроса/вставки/обновления через MongoEngine)?

Пример запроса агрегирования, который я хотел бы выполнить, выглядит следующим образом (этот запрос возвращает мне именно ту информацию, которую я хочу в оболочке Mongo):

db.entry.aggregate([
    { '$group' : 
        { '_id' : { 'carrier' : '$carrierA', 'category' : '$category' }, 
          'count' : { '$sum' : 1 }
        }
    }
])

Пример вывода из этого запроса:

{ "_id" : { "carrier" : "Carrier 1", "category" : "XYZ" }, "count" : 2 }
{ "_id" : { "carrier" : "Carrier 1", "category" : "ABC" }, "count" : 4 }
{ "_id" : { "carrier" : "Carrier 2", "category" : "XYZ" }, "count" : 31 }
{ "_id" : { "carrier" : "Carrier 2", "category" : "ABC" }, "count" : 6 }

Ответ 1

Класс, который вы определяете с помощью Mongoengine, фактически имеет метод _get_collection(), который получает "необработанный" объект коллекции, реализованный в драйвере pymongo.

Я просто использую имя Model здесь как заполнитель для вашего фактического класса, определенного для соединения в этом примере:

Model._get_collection().aggregate([
    { '$group' : 
        { '_id' : { 'carrier' : '$carrierA', 'category' : '$category' }, 
          'count' : { '$sum' : 1 }
        }
    }
])

Таким образом, вы всегда можете получить доступ к объектам pymongo, не устанавливая отдельное соединение. Mongoengine сам построен на pymongo.

Ответ 2

aggregate доступен с Mongoengine 0.9. Ссылка на Справочник API.

Как нет никакого примера вокруг, вот как вы выполняете агрегированный запрос, используя структуру агрегации с Mongoengine > 0.9

pipeline = [
  { '$group' : 
    { '_id' : { 'carrier' : '$carrierA', 'category' : '$category' }, 
      'count' : { '$sum' : 1 }
    }
  }]

Model.objects().aggregate(*pipeline)