MongoDB - 在单个查询中提取和更新
MongoDB - Pull and Update in a single query
我有以下架构 -
{
"_id" : ObjectId("60c3253f19862e6347bc9f4e"),
"farm_id": "Gustavo-chainer",
"first_ts" : ISODate("2021-05-18T09:53:00.000Z"),
"last_ts" : ISODate("2021-05-18T12:53:00.000Z"),
"sensor_data" : [
{
"data" : 76.0,
"sensor": "temperature-sensor",
"start_ts" : ISODate("2021-05-18T09:33:00.000Z"),
"end_ts" : ISODate("2021-05-18T09:53:00.000Z")
},
{
"data" : 74.0,
"sensor": "temperature-sensor",
"start_ts" : ISODate("2021-05-18T12:33:00.000Z"),
"end_ts" : ISODate("2021-05-18T12:53:00.000Z")
}
]
}
其中 first_ts = sensor_data 数组中存在的 start_ts 的所有值的最小值,并且 last_ts = end_ts 的所有值的最大值出现在 sensor_data 数组中。
我想从给定 start_ts 和 end_ts 的 sensor_data 数组中删除一个数据点,删除后,必须 更新 first_ts并且 last_ts 相应地 .
例子-
删除数据点 "start_ts" : ISODate("2021-05-18T12:33:00.000Z") 和 "end_ts" : ISODate("2021-05-18T12: 53:00.000Z”)。删除后,文档应该看起来像 -
{
"_id" : ObjectId("60c3253f19862e6347bc9f4e"),
"first_ts" : ISODate("2021-05-18T09:53:00.000Z"),
"last_ts" : ISODate("2021-05-18T09:53:00.000Z"),
"sensor_data" : [
{
"data" : 76.0,
"sensor": "temperature-sensor"
"start_ts" : ISODate("2021-05-18T09:33:00.000Z"),
"end_ts" : ISODate("2021-05-18T09:53:00.000Z")
}
]
}
我需要编写一个 pymongo 可以在单个查询中完成上述任务的查询。
您可以尝试 update with aggregation pipeline 从 MongoDB 4.2 开始,
$filter
迭代 sensor_data
数组的循环,检查字段日期条件和 $not
的相反条件以排除匹配的文档
$min
从 sensor_data.start_ts
获取最小 start_ts
日期
$max
从 sensor_data.end_ts
获取最大 end_ts
日期
collection.update(
{
sensor_data: {
$elemMatch: {
start_ts: ISODate("2021-05-18T12:33:00.000Z"),
end_ts: ISODate("2021-05-18T12:53:00.000Z")
}
}
},
[{
$set: {
sensor_data: {
$filter: {
input: "$sensor_data",
cond: {
$not: {
$and: [
{ $eq: ["$$this.start_ts", ISODate("2021-05-18T12:33:00.000Z")] },
{ $eq: ["$$this.end_ts", ISODate("2021-05-18T12:53:00.000Z")] }
]
}
}
}
}
}
},
{
$set: {
first_ts: { $min: "$sensor_data.start_ts" },
last_ts: { $max: "$sensor_data.end_ts" }
}
}],
{ multi: true }
)
我有以下架构 -
{
"_id" : ObjectId("60c3253f19862e6347bc9f4e"),
"farm_id": "Gustavo-chainer",
"first_ts" : ISODate("2021-05-18T09:53:00.000Z"),
"last_ts" : ISODate("2021-05-18T12:53:00.000Z"),
"sensor_data" : [
{
"data" : 76.0,
"sensor": "temperature-sensor",
"start_ts" : ISODate("2021-05-18T09:33:00.000Z"),
"end_ts" : ISODate("2021-05-18T09:53:00.000Z")
},
{
"data" : 74.0,
"sensor": "temperature-sensor",
"start_ts" : ISODate("2021-05-18T12:33:00.000Z"),
"end_ts" : ISODate("2021-05-18T12:53:00.000Z")
}
]
}
其中 first_ts = sensor_data 数组中存在的 start_ts 的所有值的最小值,并且 last_ts = end_ts 的所有值的最大值出现在 sensor_data 数组中。
我想从给定 start_ts 和 end_ts 的 sensor_data 数组中删除一个数据点,删除后,必须 更新 first_ts并且 last_ts 相应地 .
例子-
删除数据点 "start_ts" : ISODate("2021-05-18T12:33:00.000Z") 和 "end_ts" : ISODate("2021-05-18T12: 53:00.000Z”)。删除后,文档应该看起来像 -
{
"_id" : ObjectId("60c3253f19862e6347bc9f4e"),
"first_ts" : ISODate("2021-05-18T09:53:00.000Z"),
"last_ts" : ISODate("2021-05-18T09:53:00.000Z"),
"sensor_data" : [
{
"data" : 76.0,
"sensor": "temperature-sensor"
"start_ts" : ISODate("2021-05-18T09:33:00.000Z"),
"end_ts" : ISODate("2021-05-18T09:53:00.000Z")
}
]
}
我需要编写一个 pymongo 可以在单个查询中完成上述任务的查询。
您可以尝试 update with aggregation pipeline 从 MongoDB 4.2 开始,
$filter
迭代sensor_data
数组的循环,检查字段日期条件和$not
的相反条件以排除匹配的文档$min
从sensor_data.start_ts
获取最小 $max
从sensor_data.end_ts
获取最大
start_ts
日期
end_ts
日期
collection.update(
{
sensor_data: {
$elemMatch: {
start_ts: ISODate("2021-05-18T12:33:00.000Z"),
end_ts: ISODate("2021-05-18T12:53:00.000Z")
}
}
},
[{
$set: {
sensor_data: {
$filter: {
input: "$sensor_data",
cond: {
$not: {
$and: [
{ $eq: ["$$this.start_ts", ISODate("2021-05-18T12:33:00.000Z")] },
{ $eq: ["$$this.end_ts", ISODate("2021-05-18T12:53:00.000Z")] }
]
}
}
}
}
}
},
{
$set: {
first_ts: { $min: "$sensor_data.start_ts" },
last_ts: { $max: "$sensor_data.end_ts" }
}
}],
{ multi: true }
)