mongodb の aggregate で日付をうまく sort したい
こんにちは
氷室京介が氷室京介を卒業するというニュースのおかげで日本中にザラついた心どうすればいいんだ問題を抱える人々が急増している今日この頃ですがみなさんは大丈夫ですか?
僕は常にザラついているので大丈夫です。
本題
日毎にある商品がどれぐらい売れているのかを一覧で表示させる画面があります。 以下はイメージです
日付, 商品ID, 販売個数 2014-06-19, product2, 3 2014-06-19, product1, 2 2014-06-19, product3, 5 2014-06-18, product3, 6 2014-06-18, product2, 3
で、以下のように並べ替えたいという依頼がありましたとさ
日付, 商品ID, 販売個数 2014-06-19, product3, 5 2014-06-19, product2, 3 2014-06-19, product1, 2 2014-06-18, product3, 6 2014-06-18, product2, 3
つまり日付、販売個数をそれぞれ降順、日付を優先という事です。 で、この作業が手こずったので忘却しないうちにメモ
やってみろ
というわけで改修前の状態は以下です。
db.collection('orders').aggregate $project: product_id: 1 ordered_at: 1 year: $year: "$ordered_at" month: $month: "$ordered_at" day: $dayOfMonth: "$ordered_at" , $group: _id: year: "$year" month: "$month" day: "$day" product_id: "$product_id" ordered_at: $last: "$ordered_at" count: $sum: 1 , (e, results)-> for r in results console.log e if e console.log moment(r.ordered_at).format('YYYY-MM-DD') + ', ' + r._id.product_id + ', ' + r.count
ordered_at, count の順番で降順に sort すればいいんじゃないのだろうか
count: $sum: 1 + $sort: + ordered_at: -1 + count: -1 , (e, results)->
結果
2014-06-19, product2, 3 2014-06-19, product3, 5 2014-06-19, product1, 2 2014-06-18, product3, 6 2014-06-18, product2, 3 2014-06-18, product1, 1 2014-06-17, product1, 1
おかしいな count の並び順が期待どおりではない。 そうか ordered_at を ymd 形式にしてから並べないとだめだった。
日付を整形
というわけで $year, $month, $day を連結させればいいんじゃないかと思ったのでさらにこうしました。
$project に以下を追加
daykey: $concat: [ {$year: "$ordered_at"}, {$month: "$ordered_at"}, {$dayOfMonth: "$ordered_at"} ]
そうしたらこうなった
$concat only supports strings, not NumberInt32
ええ!?なんだって!?(オーディエンスにもっと声をだせと煽る時の氷室京介風に)
解決策を探す
で文字列にする方法を探しだし、こうやって解決できた
daykey: $concat: [ $substr: [{$year: "$ordered_at"}, 0, 4] '-' $substr: [{$month: "$ordered_at"}, 0, 2] '-' $substr: [{$dayOfMonth: "$ordered_at"}, 0, 2] ]
おしまい