mongodb按天查询数量
2020-05-15 本文已影响0人
我已不是少年郎
1、引言
最近做报表,日志都是存入mongodb,所以需要从mongodb统计查询。
需求:
1、按天查询当天日志条数。
2、返回当天日期和条数2个字段。
2、填坑关键点
2.1、时区问题
ISODate为0时区,查询时需要加入时区"timezone" : "Asia/Shanghai"
,否则凌晨8点以前的数据会归入前一天的日期。
3、解决过程
3.1、插入的文档格式
{
"_id" : "1b21f6ebf1814b1f853d31d912648956",
"createTime" : ISODate("2020-04-15T14:40:24.000+08:00")
}
3.2、插入的java代码字段
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
@Data
@Document(collection = "deviceLog")
public class DeviceLog {
@Id
private String logId;
private Date createTime;
}
3.3、查询脚本
db.deviceLog.aggregate([
{ "$project" : { "createTime" : 1, "name" : { "$dateToString" : { "format" : "%Y-%m-%d", "date" : "$createTime" ,"timezone" : "Asia/Shanghai"}}}},
{ "$group" : { "_id" : "$name", "value" : { "$sum" : 1}}},
{ "$project" : { "value" : 1, "name" : "$_id"}},
{ "$sort" : { "name" : 1}}
])
3.4、查询结果
{
"_id" : "2020-04-15",
"value" : 3.0,
"name" : "2020-04-15"
}
3.5、查询java代码
String startDay = "2020-04-01";
String endDay = "2020-04-21";
//将字符日期转java.util.Date,自行转换即可
Date startDate = DateUtils.stringToDate(startDay, DateUtils.DATE_PATTERN);
Date endDate = DateUtils.stringToDate(endDay, DateUtils.DATE_PATTERN);
Criteria whereCri = new Criteria();
whereCri.and("createTime").gte(startDate).lte(endDate);
Aggregation agg = Aggregation.newAggregation(
// 匹配查询
Aggregation.match(whereCri),
// 设置时区,返回参数
Aggregation.project("createTime").andExpression(
"{$dateToString:{format:'%Y-%m-%d',date:'$createTime',timezone: 'Asia/Shanghai'}}")
.as("name"),
// 按条件分组
Aggregation.group("name").count().as("value"),
// 返回参数2
Aggregation.project("value").and("_id").as("name"),
//排序
Aggregation.sort(Sort.Direction.ASC, "name")
);
log.error("agg:{}", agg.toString());
AggregationResults<NameValueEntity> dataResult = mongoTemplate.aggregate(agg, DeviceLog.class, NameValueEntity.class);
List<NameValueEntity> data = dataResult.getMappedResults();
log.error("size:{} data:{}", data.size(), data.toArray());
NameValueEntity.java
@Data
public class NameValueEntity implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private Long value;
}