mongo 仅查询 select 月初
mongo query select only first of month
是否可以仅查询 mongo 日期字段的月份的第一天(或最后一天或任何一天?)。
我经常使用 $date aggregation operators 但在 $group 子句中。
基本上我有一个字段,该字段已经针对每个月的每一天进行了聚合(平均)。我只想 select 这些天中的一天(以值作为整个月的代表。)
以下是 2014 年 1 月 1 日至 2015 年 2 月 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}
方法一。
我目前 运行 使用 $month 数据(并对 price
求和)的聚合,但一个问题是我试图检索基础日期值 ISODate("2015-02-01T00:00:00Z") 与几个日期聚合附带的 0,1,2 值(在周、月、年的第一天循环)。 mod(28) 约会?
方法二
我想简单地挑出 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 天的月份......不要那么在意。
非agg可以,但也行不通。又名 {"date": { "$mod": [ 28, 0 ]} }
要选择每个月的第一天(方法 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 })
是否可以仅查询 mongo 日期字段的月份的第一天(或最后一天或任何一天?)。
我经常使用 $date aggregation operators 但在 $group 子句中。
基本上我有一个字段,该字段已经针对每个月的每一天进行了聚合(平均)。我只想 select 这些天中的一天(以值作为整个月的代表。)
以下是 2014 年 1 月 1 日至 2015 年 2 月 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}
方法一。
我目前 运行 使用 $month 数据(并对 price
求和)的聚合,但一个问题是我试图检索基础日期值 ISODate("2015-02-01T00:00:00Z") 与几个日期聚合附带的 0,1,2 值(在周、月、年的第一天循环)。 mod(28) 约会?
方法二
我想简单地挑出 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 天的月份......不要那么在意。
非agg可以,但也行不通。又名 {"date": { "$mod": [ 28, 0 ]} }
要选择每个月的第一天(方法 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 })