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

时间:2019-06-16 09:32:09

标签: 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聚合管道(mongo 3.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
    }
  }

https://mongoplayground.net/p/moBRI2Q7aGu

这给了我(注意,缺少ID C,因为它没有0值):

id value   first      last
A  0       2 Jan 18   3 Jan 18
B  0       16 Jan 18  16 Jan 18

如果我查看“第一个”日期,那是那些值首先从非零变为0的日期。

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

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阶段,所以https://mongoplayground.net/p/YTP-NBJtO4R,并使用第一个聚合管道的结果集对此进行过滤。我是通过第一个结果集上的左联接在熊猫中执行此操作的,但这似乎不太好。

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

1 个答案:

答案 0 :(得分:1)

我认为这应该为您提供所需的输出:

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
    }
  }
])

如果需要的只是“ all_values”中的数据,则可以选择添加$ project和$ unwind阶段。