是否可以只查询mongo日期字段的第一天(或最后一个或任何一个?)日。
我定期使用$date aggregation operators但在$ group子句中。
基本上我有一个已经为每个月的每一天汇总(平均)的字段。我想只选择其中一天(价值作为整个月的代表。)
以下是2014年1月1日至2015年1月1日的记录集样本,其中price
为每日价格,28day_avg
为28天的结尾月平均值。
{ "date" : ISODate("2014-01-01T00:00:00Z"), "_id" : ObjectId("533b3697574e2fd08f431cff"), "price": 59.23, "28day_avg": 54.21}
{ "date" : ISODate("2014-01-02T00:00:00Z"), "_id" : ObjectId("533b3697574e2fd08f431cff"), "price": 58.75, "28day_avg": 54.15}
...
{ "date" : ISODate("2015-02-01T00:00:00Z"), "_id" : ObjectId("533b3697574e2fd08f431cff"), "price": 123.50, "28day_avg": 122.25}
方法1。
即时通讯正在使用$ month数据运行聚合(并总结price
),但有一个问题是我想要检索基础日期值ISODate(“2015-02-01T00:00:00Z”)与0,1 ,2个值与几个日期聚合一起出现(在一周,一年,一年的第一个循环)。 mod(28)约会?
方法2
我想简单地将28day_avg
的单个记录作为该时期的代表。这个月的第一天就足够了
所需的输出是......
_id: ISODate("2015-02-01T00:00:00Z"), value: 122.25,
_id: ISODate("2015-01-01T00:00:00Z"), value: 120.78,
_id: ISODate("2014-12-01T00:00:00Z"), value: 118.71,
...
_id: ISODate("2014-01-01T00:00:00Z"), value: 53.21,
当然,价值将从方法1到方法2不等,但这很好。一个是28天落后而另一个将占28天,30天,31个月......不关心那么多。
非聚集是好的,但也不起作用。又名{"date": { "$mod": [ 28, 0 ]} }
答案 0 :(得分:2)
要选择每月的第一个月(方法2),请使用以下聚合:
db.test.aggregate([
{ "$project" : { "_id" : "$date", "day" : { "$dayOfMonth" : "$date" }, "28day_avg" : 1 } },
{ "$match" : { "day" : 1 } }
])
您无法使用索引进行匹配,因此效率不高。我建议在每个包含$dayOfMonth
值的文档中添加另一个字段,这样您就可以对其进行索引并进行简单的查找:
{
"date" : ISODate("2014-01-01T00:00:00Z"),
"price" : 59.23,
"28day_avg" : 54.21,
"dayOfMonth" : 1
}
db.test.ensureIndex({ "dayOfMonth" : 1 })
db.test.find({ "dayOfMonth" : 1 }, { "_id" : 0, "date" : 1, "28day_avg" : 1 })