Поле агрегирования группы "От" должно быть определено как выражение внутри объекта

У меня есть сбор сообщений в базе данных enron.

Чтобы показать структуру коллекции, я использую эту команду.

db.messages.findOne()

{
    "_id" : ObjectId("4f16fc97d1e2d32371003f02"),
    "body" : "COURTYARD\n\nMESQUITE\n2300 HWY 67\nMESQUITE, TX  75150\ntel: 972-681-3300\nfax: 972-681-3324\n\nHotel Information: http://courtyard.com/DALCM\n\n\nARRIVAL CONFIRMATION:\n Confirmation Number:84029698\nGuests in Room: 2\nNAME: MR ERIC  BASS \nGuest Phone: 7138530977\nNumber of Rooms:1\nArrive: Oct 6 2001\nDepart: Oct 7 2001\nRoom Type: ROOM - QUALITY\nGuarantee Method:\n Credit card guarantee\nCANCELLATION PERMITTED-BEFORE 1800 DAY OF ARRIVAL\n\nRATE INFORMATION:\nRate(s) Quoted in: US DOLLAR\nArrival Date: Oct 6 2001\nRoom Rate: 62.10  per night. Plus tax when applicable\nRate Program: AAA AMERICAN AUTO ASSN\n\nSPECIAL REQUEST:\n NON-SMOKING ROOM, GUARANTEED\n   \n\n\nPLEASE DO NOT REPLY TO THIS EMAIL \nAny Inquiries Please call 1-800-321-2211 or your local\ninternational toll free number.\n \nConfirmation Sent: Mon Jul 30 18:19:39 2001\n\nLegal Disclaimer:\nThis confirmation notice has been transmitted to you by electronic\nmail for your convenience. Marriott record of this confirmation\nnotice is the official record of this reservation. Subsequent\nalterations to this electronic message after its transmission\nwill be disregarded.\n\nMarriott is pleased to announce that High Speed Internet Access is\nbeing rolled out in all Marriott hotel brands around the world.\nTo learn more or to find out whether your hotel has the service\navailable, please visit Marriott.com.\n\nEarn points toward free vacations, or frequent flyer miles\nfor every stay you make!  Just provide your Marriott Rewards\nmembership number at check in.  Not yet a member?  Join for free at\nhttps://member.marriottrewards.com/Enrollments/enroll.asp?source=MCRE\n\n",
    "filename" : "2.",
    "headers" : {
        "Content-Transfer-Encoding" : "7bit",
        "Content-Type" : "text/plain; charset=us-ascii",
        "Date" : ISODate("2001-07-30T22:19:40Z"),
        "From" : "[email protected]",
        "Message-ID" : "<[email protected]>",
        "Mime-Version" : "1.0",
        "Subject" : "84029698 Marriott  Reservation Confirmation Number",
        "To" : [
            "[email protected]"
        ],
        "X-FileName" : "eric bass 6-25-02.PST",
        "X-Folder" : "\\ExMerge - Bass, Eric\\Personal",
        "X-From" : "[email protected]",
        "X-Origin" : "BASS-E",
        "X-To" : "[email protected]",
        "X-bcc" : "",
        "X-cc" : ""
    },
    "mailbox" : "bass-e",
    "subFolder" : "personal"
}

Мне нужно получить результат от пар 'от' и 'до'. Для этого я использую команду aggregate. Прежде всего, я использую {"$unwind": "$headers.To"}, чтобы разгруппировать всю электронную почту с заголовков массива. Чем я использую раздел $group для группировки моего результата.

Я использую этот запрос:

db.messages.aggregate([{"$unwind": "$headers.To"},
    {"$group": { "_id":null, 'From': "$headers.From", 'To': "$headers.To","count":{$sum:1}}},
    {"$sort": {"count": -1}},
    {"$limit": 10},
    ])

Сообщение об ошибке:

assert: command failed: {
    "ok" : 0,
    "errmsg" : "the group aggregate field 'From' must be defined as an expression inside an object",
    "code" : 15951
} : aggregate failed
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/assert.js:13:14
[email protected]/mongo/shell/assert.js:287:5
[email protected]/mongo/shell/collection.js:1312:5
@(shell):1:1

2016-11-24T20:07:50.827+0200 E QUERY    [thread1] Error: command failed: {
    "ok" : 0,
    "errmsg" : "the group aggregate field 'From' must be defined as an expression inside an object",
    "code" : 15951
} : aggregate failed :
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/assert.js:13:14
[email protected]/mongo/shell/assert.js:287:5
[email protected]/mongo/shell/collection.js:1312:5
@(shell):1:1

Что я сделал неправильно?

Ответ 1

То, что вы хотите достичь - при условии, что вы хотите группировать от и до -, может быть выполнено со следующим group:

{"$group": { "_id": {'From': "$headers.From", 'To': "$headers.To"}, "count": {$sum:1}}}

Из справочной документации:

$group

     

Группирует документы по определенному выражению и выводит на следующий этап документ для каждой отдельной группировки. Выходные документы содержат поле _id, которое содержит отдельную группу по ключу. Выходные документы также могут содержать вычисленные поля, в которых хранятся значения некоторого выражения аккумулятора, сгруппированного по полю _id группы

Выражения аккумулятора представляют собой выражения, такие как min, max (для каждой группы), sum (как вы уже использовали), выражение массивов (указано push и addToSet) и другие.

В частности, сообщение об ошибке отмечает, что вы должны использовать одно из вышеупомянутых выражений как значение для поля Form.

Если вам не нравятся From и To "сжатые" внутри _id, вы можете позже потратить его, добавив этап $project.