MongoDB - 每天过滤一个文档

时间:2016-07-16 22:07:50

标签: mongodb mongodb-query aggregation-framework

我有一系列活动。在我的应用程序中,这些事件每天都会多次添加到事件集合中。每个事件都有一个eventName属性,它是一个字符串。每个事件还有一个包含几个数据点的数据对象。其中一些数据点全天都在变化,但其中一个数据点保持不变。我希望整天保持相同的数据。 我想写一个mongo查询来获取eventName turnOn的事件,但我每天只想要一个。

我的收藏:

/* 1 */
{
    "_id" : ObjectId("5789449365109ca974906921"),
    "eventDate" : ISODate("2016-07-15T20:16:18.508Z"),
    "eventName": "turnOff",
    "data" : {
        "sameAllDay" : 2000,
        "variesAllDay1" : 1234,
        "variesAllDay2" : 2345,
    }
}

/* 2 */
{
    "_id" : ObjectId("5789449365109ca974906921"),
    "eventDate" : ISODate("2016-07-15T20:16:13.592Z"),
    "eventName": "turnOn",
    "data" : {
        "sameAllDay" : 2000,
        "variesAllDay1" : 1235,
        "variesAllDay2" : 2346,
    }
}

/* 3 */
{
    "_id" : ObjectId("5789449365109ca974906921"),
    "eventDate" : ISODate("2016-07-15T20:16:03.507Z"),
    "eventName": "turnOff",
    "data" : {
        "sameAllDay" : 2000,
        "variesAllDay1" : 1236,
        "variesAllDay2" : 2347,
    }
}

/* 4 */
{
    "_id" : ObjectId("5789449365109ca974906921"),
    "eventDate" : ISODate("2016-07-15T20:15:58.592Z"),
    "eventName": "turnOn",
    "data" : {
        "sameAllDay" : 2000,
        "variesAllDay1" : 1237,
        "variesAllDay2" : 2348,
    }
}

/* 5 */
{
    "_id" : ObjectId("5789449365109ca974906921"),
    "eventDate" : ISODate("2016-07-16T20:15:48.507Z"),
    "eventName": "turnOn",
    "data" : {
        "sameAllDay" : 3000,
        "variesAllDay1" : 1238,
        "variesAllDay2" : 2349,
    }
}

/* 6 */
{
    "_id" : ObjectId("5789449365109ca974906921"),
    "eventDate" : ISODate("2016-07-16T20:16:18.508Z"),
    "eventName": "turnOn",
    "data" : {
        "sameAllDay" : 3000,
        "variesAllDay1" : 1209,
        "variesAllDay2" : 9876,
    }
}

我想要的是什么:

/* 2 */
{
    "_id" : ObjectId("5789449365109ca974906921"),
    "eventDate" : ISODate("2016-07-15T20:16:13.592Z"),
    "eventName": "turnOn",
    "data" : {
        "sameAllDay" : 2000,
        "variesAllDay1" : 1235,
        "variesAllDay2" : 2346,
    }
}

/* 5 */
{
    "_id" : ObjectId("5789449365109ca974906921"),
    "eventDate" : ISODate("2016-07-16T20:15:48.507Z"),
    "eventName": "turnOn",
    "data" : {
        "sameAllDay" : 3000,
        "variesAllDay1" : 1238,
        "variesAllDay2" : 2349,
    }
}

到目前为止,这是我的查询:

db.getCollection('event').aggregate([
  {$match: { 'eventName': 'turnOn' }}, 
  {$sort: { 'eventDate': -1 } }
  //filter to one event per day
])

如何获得一组turnOn事件,其中集合中的每个事件都有一个独特的日子?一天中的时间无关紧要。月份和年份很重要。

1 个答案:

答案 0 :(得分:1)

你可以这样做:

  • 2 $project(另外一个为concat年 - 月 - 日)
  • 1 $match
  • 1 $group
  • 1 $sort

mongo查询是:

db.event.aggregate([{
  $project: {
    _id: 1,
    eventName: 1,
    data: 1,
    day: {
      "$dayOfMonth": "$eventDate"
    },
    month: {
      "$month": "$eventDate"
    },
    year: {
      "$year": "$eventDate"
    }
  }
}, {
  $project: {
    _id: 1,
    eventName: 1,
    data: 1,
    eventDate: {
      $concat: [{
          $substr: ["$year", 0, 4]
        },
        "-", {
          $substr: ["$month", 0, 2]
        },
        "-", {
          $substr: ["$day", 0, 2]
        }
      ]
    }
  }
}, {
  $match: {
    "eventName": "turnOn"
  }
}, {
  $group: {
    _id: "$eventDate",
    eventDate: {
      $first: "$eventDate"
    },
    data: {
      $first: '$data'
    }
  }
}, {
  $sort: {
    eventDate: 1
  }
}])

它将执行以下操作:

  • 第一$project:从日期开始分年/月/日
  • 第二$project:联合日期
  • $match您的eventName
  • $group创建日期年 - 月 - 日,只有第一个日期&第一个数据
  • $sort日期

输出为您提供:

{
  "_id": "2016-7-15",
  "eventDate": "2016-7-15",
  "data": {
    "sameAllDay": 2000,
    "variesAllDay1": 1235,
    "variesAllDay2": 2346
  }
} {
  "_id": "2016-7-16",
  "eventDate": "2016-7-16",
  "data": {
    "sameAllDay": 3000,
    "variesAllDay1": 1238,
    "variesAllDay2": 2349
  }
}