查询mongo以检测时间序列中的值变化

时间:2019-04-10 06:54:53

标签: mongodb mongodb-query aggregation-framework

我想知道在MongoDB中是否可能进行以下操作。

我收集了一些表示时间上某些值变化的文档:

{
  "day" : ISODate("2018-12-31T23:00:00.000Z"),
  "value": [some integer value]
}

数据中没有“漏洞”,我有一段时间内所有天的条目。

是否可以查询此集合以仅获取具有与上一个不同的值的文档(按天升序排序时)?例如,具有以下文档:

{
      "day" : ISODate("2019-04-01T00:00:00.000Z"),
      "value": 10
},
{
      "day" : ISODate("2019-04-02T00:00:00.000Z"),
      "value": 10
},
{
      "day" : ISODate("2019-04-03T00:00:00.000Z"),
      "value": 15
},
{
      "day" : ISODate("2019-04-04T00:00:00.000Z"),
      "value": 15
},
{
      "day" : ISODate("2019-04-05T00:00:00.000Z"),
      "value": 15
},
{
      "day" : ISODate("2019-04-06T00:00:00.000Z"),
      "value": 10
}

我想检索2018-04-01、2018-04-03和2018-04-06的文档。

我再次发布此问题,因为前一个被错误地标记为重复。

1 个答案:

答案 0 :(得分:2)

您需要获取成对的连续文档才能检测出差距。为此,您可以将所有文档放入单个数组,然后zip将其自身从头移1个元素:

db.collection.aggregate([
    { $sort: { day: 1 } },
    { $group: { _id: null, docs: { $push: "$$ROOT" } } },
    { $project: {
        pair: { $zip: {
            inputs:[ { $concatArrays: [ [false], "$docs" ] }, "$docs" ]            
        } }
    } },
    { $unwind: "$pair" },
    { $project: {
        prev: { $arrayElemAt: [ "$pair", 0 ] },
        next: { $arrayElemAt: [ "$pair", 1 ] }
    } },
    { $match: {
         $expr: { $ne: ["$prev.value", "$next.value"] } 
    } },
    { $replaceRoot:{ newRoot: "$next" } }
])

其余的内容微不足道-您将数组展开回文档,比较对,过滤掉相等的对,然后从剩下的内容中replaceRoot