- 简单的分组
// 原生写法
db.deviceDataCollection.aggregate([
{
$match: {
"tenantId": "1475652926985990144",
"ts": {
$gt: ISODate("2022-09-15T03:39:36Z")
},
"statusData": {
"$ne": null,
"$exists": true
}
}
},
{
$sort: {
"ts": - 1
}
},
{
$group: {
_id:
"$deviceId",
ts:
{
"$first": "$ts"
}
}
},
{
$match: {
"deviceId": "1"
}
},
{
$limit: 10
}
])
// java mongoTemplate
Criteria criteria1 = new Criteria();
Criteria criteria2 = new Criteria();
Date endDate = new Date();
Date startDate = new Date(endDate.getTime() - 24 * TIME_ONE_HOUR);
criteria1.and("ts").gt(startDate).lt(endDate);
criteria1.and("statusData").exists(true);
criteria2.and("statusData.online").is("1");
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(criteria1),
Aggregation.sort(Sort.Direction.DESC, "ts"),
Aggregation.group("deviceId")
.first("_id").as("id")
.first("deviceId").as("deviceId")
.first("ts").as("ts")
.first("deviceManufacture").as("deviceManufacture")
.first("statusData").as("statusData"),
Aggregation.match(criteria2),
new SkipOperation((pageNum - 1) * pageSize),
Aggregation.limit(pageSize)
);
AggregationResults<DeviceDataEntity> aggregationResults = mongoTemplate.aggregate(agg, DEFAULT_COLLECTION_NAME, DeviceDataEntity.class);
List<DeviceDataEntity> mappedResults = aggregationResults.getMappedResults();
- 对时间分组后并统计
// 原生写法
db.deviceDataCollection_1452589816758669312.aggregate([
{
$match: {
"deviceId": "84fd27fffe71b688",
"huatuoDeviceData.commandType": "Data",
"huatuoDeviceData.sleepBandInfo.status": NumberInt("0"),
"ts": {
$gt: ISODate("2022-09-15T03:39:36Z"),
$lt: ISODate("2022-09-15T03:39:36Z")
}
}
},
{
$project: {
date: {
$dateToString: {
format: '%Y-%m-%d %H:%M',
date: '$ts',
timezone: "+08:00"
}
}
}
},
{
$group: {
_id:
"$date",
count: {
// 1表示 出现一次 统计1次
$sum: 1
}
}
},
{
$match: {
"count": {
$gte: 10
}
}
}
])
// java mongodbTemplate
String patternType = "%Y-%m-%d %H:%M";
Criteria criteria1 = new Criteria();
Criteria criteria2 = new Criteria();
criteria1.and("deviceId").is(deviceId);
criteria1.and("huatuoDeviceData.sleepBandInfo.status").is(0);
criteria2.and("count").gte(10);
Date startDate = string2Date(startTime, LocalDateTimeUtils.YYYY_MM_DD_HH_MM_SS);
Date endDate = string2Date(endTime, LocalDateTimeUtils.YYYY_MM_DD_HH_MM_SS);
if (startDate != null && endDate != null) {
criteria1.and("ts").gte(startDate).lte(endDate);
}
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(criteria1),
Aggregation.project("ts")
.and(DateOperators.DateToString.dateOf("ts").toString(patternType)).as("date"),
Aggregation.group("date").count().as("count"),
Aggregation.match(criteria2)
);
AggregationResults<DeviceDataEntity> aggregationResults =
mongoTemplate.aggregate(agg, getCollectionName(tenantId), DeviceDataEntity.class);
return aggregationResults.getMappedResults().size();
2.1. 分组后 结果是list 再聚合
db.getCollection("deviceDataCollection_1481152175999807489").aggregate([
{
"$match": {
"deviceId": "JPUS000407",
"commonDeviceData.extraCode": "291",
"commonDeviceData.commonDeviceExtraData.status": "5",
"commonDeviceData.commonDeviceExtraData.snoreTimes": {
"$ne": 0
},
"ts": {
"$gte": ISODate("2022-09-21T12:00:07Z"),
"$lte": ISODate("2022-09-22T00:00:07Z")
}
}
},
{
"$group": {
"_id": {
$dateToString: {
format: '%Y-%m-%d %H:%M:%S',
date: '$commonDeviceData.eventTime'
}
},
"snore": {
"$push": "$commonDeviceData.commonDeviceExtraData.snoreTimes"
}
}
}
])
用 $push 结果会是list 无法统计 所以要给一个策略 取list里的哪一条
db.getCollection("deviceDataCollection_1481152175999807489").aggregate([
{
"$match": {
"deviceId": "JPUS000407",
"commonDeviceData.extraCode": "291",
"commonDeviceData.commonDeviceExtraData.snoreTimes": {
"$ne": 0
},
"ts": {
"$gte": ISODate("2022-09-21T12:00:07Z"),
"$lte": ISODate("2022-09-22T00:00:07Z")
}
}
},
{
"$project": {
date: {
$dateToString: {
format: '%Y-%m-%d %H:%M:%S',
date: '$ts'
}
},
"snore":
"$commonDeviceData.commonDeviceExtraData.snoreTimes",
"deviceId": "$deviceId"
}
},
{
"$group": {
"_id": "$date"
,
"snore": {
"$first": "$snore"
},
"deviceId": {
"$first": "$deviceId"
}
}
},
{
"$group": {
"_id": "$deviceId",
count: {
"$sum": "$snore"
}
}
}
])
用$first 取每组第一条 , 得到list, 再根据一个deviceId(相同的字段) 将list聚合成一条.
String patternType = "%Y-%m-%d %H:%M:%S";
Criteria snoreCriteria = new Criteria();
snoreCriteria.and("deviceId").is(deviceId);
snoreCriteria.and("commonDeviceData.extraCode").is("291");
if (startDate != null && endDate != null) {
snoreCriteria.and("ts").gte(startDate).lte(endDate);
}
snoreCriteria.and("commonDeviceData.commonDeviceExtraData.snoreTimes").ne(0);
Aggregation snoreAgg = Aggregation.newAggregation(
Aggregation.match(snoreCriteria),
Aggregation.project("commonDeviceData.eventTime", "commonDeviceData.commonDeviceExtraData.snoreTimes", "deviceId")
.and(DateOperators.DateToString.dateOf("ts").toString(patternType)).as("date")
.and("commonDeviceData.commonDeviceExtraData.snoreTimes").as("snore")
.and("deviceId").as("deviceId"),
Aggregation.group("date")
.first("snore").as("snore")
.first("deviceId").as("deviceId"),
Aggregation.group("deviceId")
.sum("snore").as("count")
);
AggregationResults<SleepDataEntity> snoreAggregationResults =
mongoTemplate.aggregate(snoreAgg, getCollectionName(tenantId), SleepDataEntity.class);
}
2.2 按半小时为一组,聚合数据
db.deviceDataCollection_1544241345868197888.aggregate([{
$match: {
"deviceId": "84fd27fffe7a277f",
"$or": [{
"commonDeviceData.commonDeviceExtraData.heartRate": {
"$ne": "0"
},
"commonDeviceData.commonDeviceExtraData.status": {
"$ne": "1"
}
}, {
"commonDeviceData.commonDeviceExtraData.status": "1"
}],
"ts": {
"$gte": ISODate("2023-02-22T12:00:00Z"),
"$lte": ISODate("2023-02-23T23:59:59Z")
}
}
}, {
$project: {
"date": {
"$subtract": [
{
"$subtract": ["$ts", new Date("1970-01-01")]
},
{
"$mod": [
{
"$subtract": ["$ts", new Date("1970-01-01")]
},
1000 * 60 * 30
]
}
]
},
"status": "$commonDeviceData.commonDeviceExtraData.status",
"heartRate": {
"$convert": {
"input": "$commonDeviceData.commonDeviceExtraData.heartRate",
"to": "int",
"onError": 0,
"onNull": 0
}
},
"respiratoryRate": {
"$convert": {
"input": "$commonDeviceData.commonDeviceExtraData.respiratoryRate",
"to": "int",
"onError": 0,
"onNull": 0
}
}
}
}, {
$group: {
"_id": "$date",
"heartRateAvg": {
"$avg": "$heartRate"
},
"breathAvg": {
"$avg": "$respiratoryRate"
},
"status": {
"$last": "$status"
},
"date": {
"$last": "$date"
}
}
}, {
$project: {
"date": {
"$add": [ISODate("1970-01-01T00:00:00Z"), "$date"]
},
"heartRateAvg": 1,
"breathAvg": 1,
"status": 1
}
}])
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(criteria),
Aggregation.project()
// 按半小时聚合,每半个小时聚合一条
.andExpression("{$subtract:{{$subtract:{'$ts',new java.util.Date(0L)}},{$mod:{{$subtract: {'$ts',new java.util.Date(0L)}},1000 * 60 * 30}}}}").as("date")
.and("commonDeviceData.commonDeviceExtraData.status").as("status")
.and(ConvertOperators.Convert.convertValueOf("commonDeviceData.commonDeviceExtraData.heartRate")
.to("int")
.onErrorReturn(0)
.onNullReturn(0))
.as("heartRate")
.and(ConvertOperators.Convert.convertValueOf("commonDeviceData.commonDeviceExtraData.respiratoryRate")
.to("int")
.onErrorReturn(0)
.onNullReturn(0))
.as("respiratoryRate"),
Aggregation.group("date")
.avg("heartRate").as("heartRateAvg")
.avg("respiratoryRate").as("breathAvg")
.last("status").as("status")
.last("date").as("date"),
Aggregation.project()
.andExpression("{$add:{new java.util.Date(0L),'$date'}}").as("date")
.and("heartRateAvg").as("heartRateAvg")
.and("breathAvg").as("breathAvg")
.and("status").as("status")
).withOptions(allowDiskOptions);
- 求平均
// 原生写法
db.deviceDataCollection_1452589816758669312.aggregate([
{
$match: {
"deviceId": "84fd27fffe71b688",
"huatuoDeviceData.sleepBandInfo.status": NumberInt("0"),
"ts": {
$gt: ISODate("2022-09-15T03:39:36Z"),
$lt: ISODate("2022-09-15T03:39:36Z")
}
}
},
{
$group: {
_id:
'$deviceId',
breathAvg: {
$avg: "$huatuoDeviceData.sleepBandInfo.breathingRate"
},
heartRateAvg: {
$avg: "$huatuoDeviceData.sleepBandInfo.heartRate"
}
}
}
])
// java template
Criteria criteria = new Criteria();
criteria.and("deviceId").is(deviceId);
criteria.and("huatuoDeviceData.sleepBandInfo.status").is(0);
Date startDate = string2Date(startTime, LocalDateTimeUtils.YYYY_MM_DD_HH_MM_SS);
Date endDate = string2Date(endTime, LocalDateTimeUtils.YYYY_MM_DD_HH_MM_SS);
if (startDate != null && endDate != null) {
criteria.and("ts").gte(startDate).lte(endDate);
}
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(criteria),
// 这里的group字段无所谓
// avg as 的字段名要和实体对应上
Aggregation.group("deviceId")
.avg("huatuoDeviceData.sleepBandInfo.breathingRate").as("breathAvg")
.avg("huatuoDeviceData.sleepBandInfo.heartRate").as("heartRateAvg")
);
AggregationResults<SleepDataEntity> aggregationResults =
mongoTemplate.aggregate(agg, getCollectionName(tenantId), SleepDataEntity.class);
if (!CollectionUtils.isEmpty(aggregationResults.getMappedResults())){
return aggregationResults.getMappedResults().get(0);
}
return null;
4.字段为字符串 处理后求平均
db.deviceDataCollection_1475652926985990144.aggregate([
{
$match: {
"_id": ObjectId("63229e80dea96d55a66a0d47")
}
},
{
$project: {
groupId: {
$convert: {
input: "$deviceId",
to: "string"
}
},
heartRate: {
$convert: {
input: "$commonDeviceData.commonDeviceExtraData.heartRate",
to: "int"
}
}
}
},
{
$group: {
_id:
"$groupId",
avghr: {
$avg: "$heartRate"
}
}
}
])
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(criteria),
Aggregation.project()
.and("deviceId").as("groupId")
.and(ConvertOperators.Convert.convertValueOf("commonDeviceExtraData.respiratoryRate").to("int").onErrorReturn(0).onNullReturn(0)).as("breathRate")
.and(ConvertOperators.Convert.convertValueOf("commonDeviceExtraData.heartRate").to("int").onErrorReturn(0).onNullReturn(0)).as("heartRate"),
Aggregation.group("groupId")
.avg("breathRate").as("avgbr")
.avg("heartRate").as("avghr")
);
5.or
db.assets_feed.find({
"tenantId": "1475652926985990144",
"categoryId": {
$in: ["62f34c86b9852679528db1e7"]
},
$or: [{
"feedId": null
}, {
"feedId": {
$exists: false
}
}]
})
public PageInfo<SimpleFeedEntity> getFeedsByCriteria(SimpleFeedEntity simpleFeedEntity, Integer pageNum, Integer pageSize) {
Criteria criteria = new Criteria();
criteria.and("tenantId").is(simpleFeedEntity.getTenantId());
criteria.and("delFlag").is(false);
if (StringUtils.isNotBlank(simpleFeedEntity.getId())) {
criteria.and("_id").is(simpleFeedEntity.getId());
}
if (StringUtils.isNotBlank(simpleFeedEntity.getFeedId())) {
criteria.and("feedId").is(simpleFeedEntity.getFeedId());
}
if (null != simpleFeedEntity.getFeedIdExist() && simpleFeedEntity.getFeedIdExist().equals(0) && StringUtils.isBlank(simpleFeedEntity.getFeedId())) {
criteria.orOperator(Criteria.where("feedId").exists(false),Criteria.where("feedId").is(null));
}
if (StringUtils.isNotBlank(simpleFeedEntity.getStartStatus())) {
criteria.and("startStatus").is(simpleFeedEntity.getStartStatus());
}
Query query = new Query(criteria);
return findPage(pageNum, pageSize, query, SimpleFeedEntity.class);
}
6.mongoDB update
db.getCollection("assets_feed").find({
"delFlag": false,
"durations.min": {
"$exists": true
}
}).forEach(function(item) {
db.getCollection("assets_feed").update({
_id: item._id
}, {
$set: {
"durations": {
"time": item.durations.min,
"unit": "minute"
}
}
});
})
7.mongoDB 批量更新
db.deviceDataCollection_1475652926985990144.update({
"orgId": "1551852978372079616"
}, {
$set: {
"orgId": "1551852978372079617"
}
}, {
multi: true
})
8.mongoDB 批量更新时间
// 时间加一天
db.getCollection("deviceDataCollection_1475652926985990144").find({
"deviceId": "SAD23423432"
}).forEach(function(item) {
db.getCollection("deviceDataCollection_1475652926985990144").update({
_id: item._id
}, {
$set: {
ts:
new Date(item.ts.getTime() + 1000 * 3600 * 24)
}
});
})