2017-01-13 1 views
3

Я имеющей группу элементов в MongoDB, как указано ниже:Multiple Вложенные группы В массиве

/* 1 */ 
{ 
    "_id" : ObjectId("58736c7f7d43c305461cdb9b"), 
    "Name" : "Kevin", 
    "pb_event" : [ 
     { 
      "event_type" : "Birthday", 
      "event_date" : "2014-08-31" 
     }, 
     { 
      "event_type" : "Anniversary", 
      "event_date" : "2014-08-31" 
     } 
    ] 
} 

/* 2 */ 
{ 
    "_id" : ObjectId("58736cfc7d43c305461cdba8"), 
    "Name" : "Peter", 
    "pb_event" : [ 
     { 
      "event_type" : "Birthday", 
      "event_date" : "2014-08-31" 
     }, 
     { 
      "event_type" : "Anniversary", 
      "event_date" : "2015-03-24" 
     } 
    ] 
} 

/* 3 */ 
{ 
    "_id" : ObjectId("58736cfc7d43c305461cdba9"), 
    "Name" : "Pole", 
    "pb_event" : [ 
     { 
      "event_type" : "Birthday", 
      "event_date" : "2015-03-24" 
     }, 
     { 
      "event_type" : "Work Anniversary", 
      "event_date" : "2015-03-24" 
     } 
    ] 
} 

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

Ожидаемый выход

/* 1 */ 
{  
    "event_date" : "2014-08-31", 
    "data" : [ 
     { 
      "event_type" : "Birthday", 
      "details" : [ 
       { 
        "_id" : ObjectId("58736c7f7d43c305461cdb9b"), 
        "name" : "Kevin" 
       }, 
       { 
        "_id" : ObjectId("58736cfc7d43c305461cdba8"), 
        "name" : "Peter" 
       } 
      ], 
      "count" : 2 
     }, 
     { 
      "event_type" : "Anniversary", 
      "details" : [ 
       { 
        "_id" : ObjectId("58736c7f7d43c305461cdb9b"), 
        "name" : "Kevin" 
       } 
      ], 
      "count" : 1 
     } 
    ] 
} 

/* 2 */ 
{ 
    "event_date" : "2015-03-24", 
    "data" : [ 
     { 
      "event_type" : "Anniversary", 
      "details" : [ 
       { 
        "_id" : ObjectId("58736cfc7d43c305461cdba8"), 
        "name" : "Peter" 
       } 
      ], 
      "count" : 1 
     }, 
     { 
      "event_type" : "Birthday", 
      "details" : [ 
       { 
        "_id" : ObjectId("58736cfc7d43c305461cdba9"), 
        "name" : "Pole" 
       } 
      ], 
      "count" : 1 
     }, 
     { 
      "event_type" : "Work Anniversary", 
      "details" : [ 
       { 
        "_id" : ObjectId("58736cfc7d43c305461cdba9"), 
        "name" : "Pole" 
       } 
      ], 
      "count" : 1 
     } 
    ] 
} 

ответ

1

Использование механизма агрегации, вам нужно будет запустить трубопровод, который имеет следующие этапы, так что вы получите желаемый результат:

db.collection.aggregate([ 
    { "$unwind": "$pb_event" }, 
    { 
     "$group": { 
      "_id": { 
       "event_date": "$pb_event.event_date", 
       "event_type": "$pb_event.event_type" 
      },    
      "details": { 
       "$push": { 
        "_id": "$_id", 
        "name": "$Name" 
       } 
      }, 
      "count": { "$sum": 1 }    
     } 
    },  
    { 
     "$group": { 
      "_id": "$_id.event_date",    
      "data": { 
       "$push": { 
        "event_type": "$_id.event_type", 
        "details": "$details", 
        "count": "$count" 
       } 
      }   
     } 
    }, 
    { 
     "$project": { 
      "_id": 0, 
      "event_date": "$_id", 
      "data": 1 
     } 
    } 
]) 

В вышеуказанном трубопроводе первым шагом является $unwind Оператор

{ "$unwind": "$pb_event" } 

который поставляется в весьма удобном виде, когда данные хранятся в виде массива. Когда оператор разматывания применяется в поле данных списка, он будет генерировать новую запись для каждого элемента поля данных списка, на котором выполняется размотка. Это в основном сглаживает данные.

Это необходимая операция для следующего этапа трубопровода, этап $group, где группа уплощенные документы по деконструкции pb_event полей массива event_date и event_type:

{ 
    "$group": { 
     "_id": { 
      "event_date": "$pb_event.event_date", 
      "event_type": "$pb_event.event_type" 
     },    
     "details": { 
      "$push": { 
       "_id": "$_id", 
       "name": "$Name" 
      } 
     }, 
     "count": { "$sum": 1 }    
    } 
}, 

Оператор конвейера $group является аналогично предложению SQL GROUP BY. В SQL вы не можете использовать GROUP BY, если не используете какие-либо функции агрегации. Точно так же вы должны использовать функцию агрегации в MongoDB (так называемый оператор аккумулятора). Вы можете больше узнать о функциях агрегации here.

В этой операции $group, логика для расчета совокупного подсчета т.е. общего количества документов в группе с использованием оператора аккумулятора в $sum. В рамках одного и того же конвейера вы можете агрегировать список подкатегорий name и _id с помощью оператора $push, который возвращает массив значений выражений для каждой группы.

Предшествующий $group трубопровод

{ 
    "$group": { 
     "_id": "$_id.event_date",    
     "data": { 
      "$push": { 
       "event_type": "$_id.event_type", 
       "details": "$details", 
       "count": "$count" 
      } 
     }   
    } 
} 

будет дополнительно агрегировать результаты последнего трубопровода путем группировки на event_date, который образует основу требуемой продукции путем создания нового списка данных с использованием $push и затем окончательный $project этап трубопровода

{ 
    "$project": { 
     "_id": 0, 
     "event_date": "$_id", 
     "data": 1 
    } 
} 

изменяет поля документов, переименовав поле _id в event_date и сохранив другое поле.

+0

@ charidam..Это можно группировать по дате месяца по вышеуказанному запросу? – 5a01d01P