mongo查询只选择月初

时间:2015-02-10 04:26:52

标签: mongodb

是否可以只查询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 ]} }

1 个答案:

答案 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 })