2014-12-08 4 views
4

Я пишу запрос в mongo db. У меня есть таблица бронирования, и я хочу получить количество заказов в месяц, то есть группу за месяцем. Я смущен тем, что, как получить месяц с даты.MongoDB - группа по месяцам

Вот моя схема:

{ 
    "_id" : ObjectId("5485dd6af4708669af35ffe6"), 
    "bookingid" : 1, 
    "operatorid" : 1, 
    "clientid" : null, 
    "callername" : "Sayem Hussain", 
    "contactno" : "0205661862", 
    "regular" : 0, 
    "bookingdetail" : [ 
     { 
      "driverid" : 1, 
      "pickupdatetime" : "2011-04-14 11:00:00", 
      "from" : "white chapel", 
      "to" : "beach", 
      "cost" : 500, 
      "journeytime" : 60 
     }, 
     { 
      "driverid" : 2, 
      "pickupdatetime" : "2012-05-14 12:00:00", 
      "from" : "walthamstow", 
      "to" : "mile end", 
      "cost" : 1000, 
      "journeytime" : 50 
     } 
    ], 
    "bookingdatetime" : "2012-10-11T07:00:00Z" 
} 
{ 
    "_id" : ObjectId("5485dd6af4708669af35ffe7"), 
    "bookingid" : 2, 
    "operatorid" : 1, 
    "clientid" : 1, 
    "callername" : null, 
    "contactno" : "0205561281", 
    "regular" : 1, 
    "bookingdetail" : [ 
     { 
      "driverid" : 3, 
      "pickupdatetime" : "2012-02-12 09:00:00", 
      "from" : "grange park", 
      "to" : "queen mary", 
      "cost" : 650, 
      "journeytime" : 90 
     }, 
     { 
      "driverid" : 2, 
      "pickupdatetime" : "2012-02-13 06:00:00", 
      "from" : "drapers bar", 
      "to" : "naveed restaurant", 
      "cost" : 1350, 
      "journeytime" : 120 
     } 
    ], 
    "bookingdatetime" : "2014-07-26T05:00:00Z" 
} 
{ 
    "_id" : ObjectId("5485dd6af4708669af35ffe8"), 
    "bookingid" : 3, 
    "operatorid" : 2, 
    "clientid" : 2, 
    "callername" : null, 
    "contactno" : "02565138632", 
    "regular" : 1, 
    "bookingdetail" : [ 
     { 
      "driverid" : 2, 
      "pickupdatetime" : "2013-11-23 06:00:00", 
      "from" : "hussainabad", 
      "to" : "lyari", 
      "cost" : 2450, 
      "journeytime" : 240 
     }, 
     { 
      "driverid" : 1, 
      "pickupdatetime" : "2013-11-25 08:00:00", 
      "from" : "garden", 
      "to" : "defence", 
      "cost" : 1800, 
      "journeytime" : 30 
     } 
    ], 
    "bookingdatetime" : "2014-03-17T11:00:00Z" 
} 

И это я попытался:

db.booking.aggregate([{$group:{_id:new Date("$bookingdatetime").getMonth(), numberofbookings:{$sum:1}}}]) 

и возвращает:

{ "_id" : NaN, "numberofbookings" : 3 } 

Где я буду неправильно? Пожалуйста, помогите мне.

+0

"bookingdatetime" : «2012-10-11T07: 00: 00Z» - это строка? –

+0

Да, это строка – user1584253

+0

Вам необходимо преобразовать ее в ISODate, а затем выполнить агрегацию. Или иначе, используйте Map/Reduce –

ответ

7

Вы не можете добавлять произвольный JavaScript в вашем агрегирования трубопровода, так потому, что вы храните bookingdatetime как string вместо Date вы не можете использовать оператор $month.

Однако, поскольку ваши даты строки следуют строгому формату, вы можете использовать оператор $substr извлечь значение месяца из строки:

db.test.aggregate([ 
    {$group: { 
     _id: {$substr: ['$bookingdatetime', 5, 2]}, 
     numberofbookings: {$sum: 1} 
    }} 
]) 

Выходы:

{ 
    "result" : [ 
     { 
      "_id" : "03", 
      "numberofbookings" : 1 
     }, 
     { 
      "_id" : "07", 
      "numberofbookings" : 1 
     }, 
     { 
      "_id" : "10", 
      "numberofbookings" : 1 
     } 
    ], 
    "ok" : 1 
} 
+0

Спасибо !!! :) :) – user1584253

+0

@JohnnyHK, вопрос такой же как это. Но разному нужно вернуть 0, если нет значений за определенный месяц ..... PLZ проверить это и дать ответ. Http: // StackOverflow.com/questions/38437797/filter-and-re-organiz-results-using-node-js-and-mongodb-matching-to-datemonth/38438154 # 38438154 –

+0

Предполагая, что вас интересует только текущий год, не будет это сломается, как только год перевернется? – colefner

7

Вам нужно использовать ключевое слово $ month в своей группе. Ваш вызов new Date().getMonth() произойдет один раз и попытается создать месяц из строки «$ bookingdatetime».

db.booking.aggregate([{$group:{_id: { $month: "$bookingdatetime" }, 
         numberofbookings:{$sum:1} } } ]); 
+1

Он дает это исключение "исключение: невозможно преобразовать из типа BSON String to Date" – user1584253

+0

Я не видел что вы храните даты в виде строки.Это вас удерживает, нет простого способа сделать это преобразование внутри оператора агрегата. Есть много людей, которые уже столкнулись с этой проблемой на SO: http: // stackoverflow. com/questions/15473772/how-to-convert-from-string-to-date-data-type –

+1

@ user1584253, вероятно, забыл ведущий «$» в поле (например, $ bookingdateti me) –

Смежные вопросы