Mongodb 查找每天的最后记录

Mongodb 查找每天的最后记录,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我使用mongodb(我是mongodb新手)来存储我的功耗数据,每分钟都有一条新记录,下面是一个示例: {"id":"5309d4cae4b0fbd904cc00e1","adco":"O","hchc":7267599,"hchp":10805900,"hhphc":"g","ptec":"c","iinst":13,"papp":3010,"imax":58,"optarif":"s","isousc":60,"motdetat":"Á","date":1393156826114} 所以

我使用mongodb(我是mongodb新手)来存储我的功耗数据,每分钟都有一条新记录,下面是一个示例:

{"id":"5309d4cae4b0fbd904cc00e1","adco":"O","hchc":7267599,"hchp":10805900,"hhphc":"g","ptec":"c","iinst":13,"papp":3010,"imax":58,"optarif":"s","isousc":60,"motdetat":"Á","date":1393156826114}
所以我每天大约有1440张唱片

我想按天计算成本,但问题是我需要当天的最后一个记录,因为这个记录可以给我绝对kWh(千瓦时)的数量。所以,如果我去掉昨天最后一个记录的kwh值,我就得到了当天的kwh值

字段
hchp
给出了这个绝对kWh。字段
date
对应于以毫秒为单位的测量时间

当天消费=当天结束时的绝对消费-昨天结束时的绝对消费

如何在mongodb中获取每天的最后一条记录

注意:我在spring java中使用mongodb,所以我需要这样一个查询:

获取所有度量值的示例:

@Query("{ 'date' : { $gt : ?0 }}")
public List<Mesure> findByDateGreaterThan(Date date, Sort sort);
@Query(“{'date':{$gt:?0}”)
查找日期大于(日期、排序)的公共列表;

比原来的答案更现代一点:

db.collection.aggregate([
  { "$sort": { "date": 1 } },
  { "$group": {
    "_id": {
      "$subtract": ["$date",{"$mod": ["$date",86400000]}]
    },
    "doc": { "$last": "$$ROOT" }
  }},
  { "$replaceRoot": { "newDocument": "$doc" } }
])
同样的原则也适用于从集合中提取数据,然后在所需的分组键上从分组边界提取数据

由于最初的编写方式是使用
$$ROOT
而不是指定每个文档属性,因此更清楚一些,当然,stage允许您将该数据完全还原为原始文档表单

但一般的解决方案仍然是首先,然后在所需的公共键上,并根据所需属性的分组边界保留或(取决于排序顺序)

另外,与问题中的时间戳值不同的是BSON日期,请参阅了解如何实际使用和返回BSON日期值为不同时间间隔进行累加的不同方法


我不太清楚你在这里要做什么,但如果我的理解是正确的,你可以总体上做到这一点。因此,要获得每天的最后一条记录:

db.collection.aggregate([
//按升序按日期顺序排序
{“$sort”:{“日期”:1}},
//日期数学转换为全天
{“$project”:{
“adco”:1,
“六氯环己烷”:1,
“hchp”:1,
“hhphc”:1,
“ptec”:1,
“iinst”:1,
“papp”:1,
“imax”:1,
“optarif”:1,
“isousc”:1,
“motdeat”:1,
“日期”:1,
“wholeDay”:{“$subtract”:[“$date”,{“$mod”:[“$date”,86400000]}]
}},
//全天分组(_id插入是单调的)
{“$组”:
“_id”:“$wholeDay”,
“docId”:{“$last”:“$\u id”},
“adco”:{“$last”:“$adco”},
“hchc”:{“$last”:“$hchc”},
“hchp”:{“$last”:“$hchp”},
“hhphc”:{“$last”:“$hhphc”},
“ptec”:{“$last”:“$ptec”},
“iinst”:{“$last”:“$iinst”},
“papp”:{“$last”:“$papp”},
“imax”:{“$last”:“$imax”},
“optarif”:{“$last”:“$optarif”,
“isousc”:{“$last”:“$isouc”},
“motdeat”:{“$last”:“$motdeat”},
“日期”:{“$last”:“$date”},
}}
])
这里的原理是,给定时间戳值,进行日期数学运算,将其投影为每天开始时的午夜时间。然后,由于文档上的
\u id
键已经是单调的(总是在增加),那么只需对
wholeDay
值进行分组,同时将
$last
文档从分组边界中拉出

如果您不需要所有字段,那么只需对所需字段进行项目和分组

是的,您可以在spring数据框架中实现这一点。我肯定里面有一个包装好的命令。但除此之外,使用本机命令的咒语是这样的:

mongoOps.getCollection(“yourCollection”).aggregate(…)
对于记录,如果您实际上有BSON日期类型,而不是时间戳作为数字,那么您可以跳过日期数学:

db.collection.aggregate([
{“$group”:{
“_id”:{
“年”:{“$year”:“$date”},
“月”:{“$month”:“$date”},
“日”:{“$dayOfMonth”:“$date”}
},
“hchp”:{“$last”:“$hchp”}
}}
])

您是否考虑过获取表示日期的范围,然后排序并限制为最高日期值?