合并mongodb聚合管道的两个阶段

合并mongodb聚合管道的两个阶段,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我在mongodb系列中有一系列价格,如下所示: id date value A 1 Jan 18 1 A 2 Jan 18 0 A 3 Jan 18 0 B 14 Jan 18 4 B 15 Jan 18 5 B 16 Jan 18 0 C 2 Jan 18 4 C 3 Jan 18 4 C 5 Jan 18 3 使用mongodb聚合管道(Mongo3.4),我试图找出每个id的值从非零变为0的日期,以及这些记录的“id组” 当记

我在mongodb系列中有一系列价格,如下所示:

id date       value
A  1 Jan 18   1
A  2 Jan 18   0
A  3 Jan 18   0
B  14 Jan 18  4
B  15 Jan 18  5
B  16 Jan 18  0
C  2 Jan 18   4
C  3 Jan 18   4
C  5 Jan 18   3
使用mongodb聚合管道(Mongo3.4),我试图找出每个id的值从非零变为0的日期,以及这些记录的“id组”

当记录具有特定值时,我可以找到第一个和最后一个日期:

{
    "$addFields": {
      "date": {
        "$dateFromString": {
          "dateString": "$date"
        }
      }
    }
  },
  {
    $group: {
      _id: {
        "id": "$id",
        "value": "$value"
      },
      "first": {
        "$first": "$date"
      },
      "last": {
        "$last": "$date"
      }
    }
  },
  {
    "$match": {
      "_id.value": 0
    }
  }

这给了我(注意id C丢失,因为它没有0值):

如果我看一下“第一个”日期,这些日期的值首先从非零变为0

但是,我希望看到这些值的整个“id组”在某个时间点从非零变为0。因此,我的预期结果是:

id value   first      last
A  1       1 Jan 18   1 Jan 18
A  0       2 Jan 18   3 Jan 18
B  4       14 Jan 18  14 Jan 18
B  5       15 Jan 18  15 Jan 18
B  0       16 Jan 18  16 Jan 18
为了实现这一点,我需要在匹配上述管道之前访问group阶段,因此,以某种方式使用来自第一个聚合管道的结果集对其进行过滤。我通过第一个结果集上的左连接在pandas中实现了这一点,但这似乎不雅观


所以现在我有两条不同的管道,这似乎有点不方便。理想情况下,最后的结果集将来自单个聚合管道。有什么想法吗?

我想这应该会让你得到你想要的结果:

db.collection.aggregate([
  {
    "$addFields": {
      "date": {
        "$dateFromString": {
          "dateString": "$date"
        }
      }
    }
  },
  {
    "$sort": {
      date: 1
    }
  },
  {
    $group: {
      _id: {
        "id": "$id",
        "value": "$value"
      },
      "first": {
        "$first": "$date"
      },
      "last": {
        "$last": "$date"
      },
      "data": {
        "$push": "$$ROOT"
      }
    }
  },
  {
    "$sort": {
      first: 1
    }
  },
  {
    "$group": {
      _id: "$_id.id",
      last_value: {
        $last: "$_id.value"
      },
      first_date_for_last_value: {
        $last: "$first"
      },
      last_date_for_last_value: {
        $last: "$last"
      },
      all_values: {
        $push: {
          id: "$$ROOT._id.id",
          value: "$$ROOT._id.value",
          first: "$first",
          last: "$last"
        }
      }
    }
  },
  {
    "$match": {
      "last_value": 0
    }
  }
])
如果您只需要“所有值”中的数据,还可以选择添加$project和$unwind阶段

db.collection.aggregate([
  {
    "$addFields": {
      "date": {
        "$dateFromString": {
          "dateString": "$date"
        }
      }
    }
  },
  {
    "$sort": {
      date: 1
    }
  },
  {
    $group: {
      _id: {
        "id": "$id",
        "value": "$value"
      },
      "first": {
        "$first": "$date"
      },
      "last": {
        "$last": "$date"
      },
      "data": {
        "$push": "$$ROOT"
      }
    }
  },
  {
    "$sort": {
      first: 1
    }
  },
  {
    "$group": {
      _id: "$_id.id",
      last_value: {
        $last: "$_id.value"
      },
      first_date_for_last_value: {
        $last: "$first"
      },
      last_date_for_last_value: {
        $last: "$last"
      },
      all_values: {
        $push: {
          id: "$$ROOT._id.id",
          value: "$$ROOT._id.value",
          first: "$first",
          last: "$last"
        }
      }
    }
  },
  {
    "$match": {
      "last_value": 0
    }
  }
])