Запрос агрегирования Flask-MongoEngine и PyMongo

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

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

В этом вопросе есть комментарий, в котором говорится, что вам нужно использовать «необработанные функции pymongo и агрегирования». " Однако примеров того, как это могло бы работать, нет. Я повозился с Python и создал базовое приложение, использующее фреймворк Flask, но вникать в полноценные приложения и подключаться / запрашивать к 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 }

person SirCobalt    schedule 25.06.2014    source источник


Ответы (2)


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

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

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

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

person Neil Lunn    schedule 26.06.2014
comment
Потрясающие! Большое тебе спасибо. Это было немного головной болью для меня, пытаясь найти решение. Я протестировал метод _get_collection () и смог получить результат от Mongo. - person SirCobalt; 01.07.2014
comment
Блестящий ответ !! Чтобы добавить к этому, если вы хотите запустить предложение group by только для определенных записей, вы можете использовать оператор $ match следующим образом: Model._get_collection().aggregate([ { '$match': qs._query, }, { '$group' : { '_id' : { 'carrier' : '$carrierA', 'category' : '$category' }, 'count' : { '$sum' : 1 } } } ]) где qs - это экземпляр набора запросов MongoEngine. - person Yahya; 31.05.2016

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

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

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

Model.objects().aggregate(*pipeline)
person Alain1405    schedule 12.09.2015