0

Mongo で日付別にデータを集計しようとしていますが、目的を達成できません。現在、私はこれを使用しています:

db.aggregData.aggregate( { $group: {_id: "$Date".toString(),  
                                   tweets: { $sum: "$CrawledTweets"} } }, 
                         { $match:{ _id: {$gte: ISODate("2013-03-19T12:31:00.247Z") }}}, 
                         { $sort: {Date:-1} } 
                       )

これは次のようになります。

"result" : [
                {
                        "_id" : ISODate("2013-03-19T12:50:00.641Z"),
                        "tweets" : 114
                },
                {
                        "_id" : ISODate("2013-03-19T12:45:00.631Z"),
                        "tweets" : 114
                },
                {
                        "_id" : ISODate("2013-03-19T12:55:00.640Z"),
                        "tweets" : 123
                },
                {
                        "_id" : ISODate("2013-03-19T12:40:00.628Z"),
                        "tweets" : 91
                    },
                {
                        "_id" : ISODate("2013-03-19T12:31:00.253Z"),
                        "tweets" : 43
                },
                {
                        "_id" : ISODate("2013-03-19T13:20:00.652Z"),
                        "tweets" : 125
                },
                {
                        "_id" : ISODate("2013-03-19T12:31:00.252Z"),
                        "tweets" : 30
                }
 ],
        "ok" : 1

うまくいっているように見えますが、さらに調べてみると、
ISODate("2013-03-19T12:31:00.253Z") と ISODate("2013-03-19T12:31:00.252Z") の繰り返しがあることがわかります。 .
変更されるのは、Z の前の最後のビットだけです。

だからここに私の質問があります。この部分は何ですか? そして、集約でそれを無視するにはどうすればよいですか?

前もって感謝します。

編集:日付で集計したいので、年/月/日全体+時間と分。残りはどうでもいい。

編集:私のdbはmongolabにあるので、2.2を使用しています

さて、私は別の方法でそれを行いました: 私はすべての日付を 0 の秒/ミリ秒で保存します。したがって、moment.js のおかげで、サーバー側のコードを少し増やすことなく、単純な集計を維持できます。

4

3 に答える 3

6

「全体」の日付で集計しようとしています。つまり、ISODate() から時間を削除しようとしていますよね? それを行うにはいくつかの方法があります。私のブログの投稿で詳しく説明しています。

Aggregation Framework を使用した愚かな日付のトリック

そこに完全な段階的な内訳を見ることができますが、要約すると、次の 2 つの選択肢があります。

  • 集約された値が であることを気にしない場合は、 ,および演算子を同相でISODate()使用して、 YMD だけを取り出して {$group} をオンにすることができます。{$year}{$month}{$dayOfMonth}{$project}

  • グループ化された値が維持されることを気にするISODate場合は、フェーズ{$subtract}の時間部分を残して型を残すことができます - 注意点は、この方法には、日付演算と演算子のサポートを追加する MongoDB 2.4 (リリースされたばかり)が必要であるということです(exact を参照)。ブログ投稿のコード)。{$project}ISODate()$millisecond

これがおそらくあなたが望むものです:

db.aggregData.aggregate([
  { 
    $project:{ 
        CrawledTweets: 1,
        newDate: { 
            year:{$year:"$Date"}, 
            month: {$month:"$Date"}, 
            day: {$dayOfMonth:"$Date"}, 
            hour: {$hour: "$Date"}, 
            min: {$minute: "$Date"}
        }   
    }   
  },
  { 
    $group: {
        _id: "$newDate",
        tweets: { $sum: "$CrawledTweets"}
    }   
  }
])
于 2013-03-20T16:35:17.203 に答える
1

Mongo の専門家でなくても、データベース フィールドを知らなくても、このようなものを思いつくでしょう。おそらく、これに基づいて構築できます。

db.aggregData.aggregate(
{ 
    $project:{ 
        CrawledTweets: 1,
        groupedTime: { 
            year:{$year:"$_id"}, 
            month: {$month:"$_id"}, 
            day: {$dayOfMonth:"$_id"}, 
            hour: {$hour: "$_id"}, 
            min: {$minute: "$_id"}
        }   
    }   
},
{ 
    $group: {
        _id: { groupedTime: "$CrawledTweets" },
        tweets: { $sum: "$tweets"}
    }   
}
)
于 2013-03-21T10:22:52.783 に答える
1

MongoDB の日付集計演算子を使用できるようになりました。Node.js での使用など、スキーマのセットアップについて説明した記事がブログに投稿されています。

http://smyl.es/how-to-use-mongodb-date-aggregation-operators-in-node-js-with-mongoose-dayofmonth-dayofyear-dayofweek-etc/

于 2013-10-14T16:11:04.707 に答える