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 的相反条件以排除匹配的文档
  • $minsensor_data.start_ts
  • 获取最小 start_ts 日期
  • $maxsensor_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 }
)

Playground