如何获取 $group 的原始值?
How to get original value in $group?
如何获取 $group 运算符中字段的原始值?
我正在使用 $group 来获取时间范围内的最大值,我还需要在其中获取一对值。
例如:
[{
time: "2021-01-01T10:15:32.000",
locationId: ObjectId("6170e536f294af00124d21d7"),
value: 36,
lat: "21.12213",
lng: "82.01929",
type: "temp"
}, {
time: "2021-01-01T10:16:32.000",
locationId: ObjectId("6170e536f294af00124d21d7"),
value: 23,
lat: "21.12213",
lng: "82.01929",
type: "temp"
}, {
time: "2021-01-01T10:16:32.000",
locationId: ObjectId("6170e536f294af00124d21d7"),
value: 26,
lat: "21.12213",
lng: "82.01929",
type: "humidity"
},{
time: "2021-01-01T10:16:32.000",
locationId: ObjectId("6170e536f294af00124d21d7"),
value: 12,
lat: "21.12213",
lng: "82.01929",
type: "humidity"
}]
这是同一个位置的数据(温度和湿度),所以纬度、经度是一样的。我使用 $group 来获取当天位置的最大温度和湿度。所以我只按天分组,不包括时间,如下所示:
[{
$group: {
_id: {
time: {
$dateToString: {
format: "%Y-%m-%d",
date: "$time"
}
},
locId: "$locationId",
type: "$type"
},
maxValue: {
$max: "$value"
},
coordinate: {
$push: {
lat: "$lat",
lng: "$lng"
}
}
}
}]
但如果是这样,温度和湿度不在同一个对象中,因为我也按 type
分组,所以我将再分组一次,仅按 time
分组。
[{
$group: {
_id: {
time: {
$dateToString: {
format: "%Y-%m-%d",
date: "$time"
}
},
locId: "$locationId",
type: "$type"
},
maxValue: {
$max: "$value"
},
coordinate: {
$push: {
lat: "$lat",
lng: "$lng"
}
}
}
}, {
$group: {
_id: "$_id.time",
maxValues: {
$push: {
value: "$maxValue",
type: "$_id.type"
}
},
coordinates: {
$last: {
$slice: ["$coordinate", -1]
}
}
}
}]
预期结果:
[{
_id: "2021-01-01",
maxValues: [{
value: 36,
type: "temp"
}, {
value: 26,
type: "humidity"
}],
cooridinates: { lat: "21.12213" , lng: "82.01929" }
}]
响应符合我的预期,但你可以看到,我必须将所有具有相同值的纬度、日志推送到一个数组,在下一组中,我得到数组中的最后一个对象,所以推送坐标是多余的,采取更多的表现。这就是为什么有时它会抛出错误:
PlanExecutor error during aggregation :: caused by :: $push used too much memory and cannot spill to disk
所以我需要找到一个新的解决方案来优化上述查询。或者修复错误。有这方面经验的请给我一个解决方案
最近遇到了类似的问题,在您的情况下,您可以尝试使用 $first
来保持 $group
中的常量值,如此处 mongo group query how to keep fields
所建议
{
$group: {
_id: {
time: {
$dateToString: {
format: "%Y-%m-%d",
date: "$time"
}
},
locId: "$locationId",
type: "$type"
},
maxValue: {
$max: "$value"
},
lat:{$first:"$lat"},
lng:{$first:"$lng"}
}
}
如何获取 $group 运算符中字段的原始值? 我正在使用 $group 来获取时间范围内的最大值,我还需要在其中获取一对值。
例如:
[{
time: "2021-01-01T10:15:32.000",
locationId: ObjectId("6170e536f294af00124d21d7"),
value: 36,
lat: "21.12213",
lng: "82.01929",
type: "temp"
}, {
time: "2021-01-01T10:16:32.000",
locationId: ObjectId("6170e536f294af00124d21d7"),
value: 23,
lat: "21.12213",
lng: "82.01929",
type: "temp"
}, {
time: "2021-01-01T10:16:32.000",
locationId: ObjectId("6170e536f294af00124d21d7"),
value: 26,
lat: "21.12213",
lng: "82.01929",
type: "humidity"
},{
time: "2021-01-01T10:16:32.000",
locationId: ObjectId("6170e536f294af00124d21d7"),
value: 12,
lat: "21.12213",
lng: "82.01929",
type: "humidity"
}]
这是同一个位置的数据(温度和湿度),所以纬度、经度是一样的。我使用 $group 来获取当天位置的最大温度和湿度。所以我只按天分组,不包括时间,如下所示:
[{
$group: {
_id: {
time: {
$dateToString: {
format: "%Y-%m-%d",
date: "$time"
}
},
locId: "$locationId",
type: "$type"
},
maxValue: {
$max: "$value"
},
coordinate: {
$push: {
lat: "$lat",
lng: "$lng"
}
}
}
}]
但如果是这样,温度和湿度不在同一个对象中,因为我也按 type
分组,所以我将再分组一次,仅按 time
分组。
[{
$group: {
_id: {
time: {
$dateToString: {
format: "%Y-%m-%d",
date: "$time"
}
},
locId: "$locationId",
type: "$type"
},
maxValue: {
$max: "$value"
},
coordinate: {
$push: {
lat: "$lat",
lng: "$lng"
}
}
}
}, {
$group: {
_id: "$_id.time",
maxValues: {
$push: {
value: "$maxValue",
type: "$_id.type"
}
},
coordinates: {
$last: {
$slice: ["$coordinate", -1]
}
}
}
}]
预期结果:
[{
_id: "2021-01-01",
maxValues: [{
value: 36,
type: "temp"
}, {
value: 26,
type: "humidity"
}],
cooridinates: { lat: "21.12213" , lng: "82.01929" }
}]
响应符合我的预期,但你可以看到,我必须将所有具有相同值的纬度、日志推送到一个数组,在下一组中,我得到数组中的最后一个对象,所以推送坐标是多余的,采取更多的表现。这就是为什么有时它会抛出错误:
PlanExecutor error during aggregation :: caused by :: $push used too much memory and cannot spill to disk
所以我需要找到一个新的解决方案来优化上述查询。或者修复错误。有这方面经验的请给我一个解决方案
最近遇到了类似的问题,在您的情况下,您可以尝试使用 $first
来保持 $group
中的常量值,如此处 mongo group query how to keep fields
{
$group: {
_id: {
time: {
$dateToString: {
format: "%Y-%m-%d",
date: "$time"
}
},
locId: "$locationId",
type: "$type"
},
maxValue: {
$max: "$value"
},
lat:{$first:"$lat"},
lng:{$first:"$lng"}
}
}