在MongoDB中查找日期范围中缺少的日期

时间:2019-05-31 04:32:58

标签: javascript mongodb mongodb-query aggregation-framework

我有一个collection,其中包含用于特定操作的serviceDate字段。 我需要查找给定日期范围内是否缺少任何serviceDate,如果找到了,则在MongoDB中的日期范围之间缺少serviceDate dates的返回列表。 我的集合的示例JSON如下。

{
    "_id" : ObjectId("5cefdb46bfbe1c0001f38413"),
    "category" : "RENT",
    "serviceDate" : ISODate("2019-06-15T05:30:00.000+05:30")
},


{
    "_id" : ObjectId("5cefdb46bfbe1c0001f38412"),
    "category" : "RENT",
    "serviceDate" : ISODate("2019-06-14T05:30:00.000+05:30")
},


{
    "_id" : ObjectId("5cefdb46bfbe1c0001f38411"),
    "category" : "RENT",
    "serviceDate" : ISODate("2019-06-13T05:30:00.000+05:30")
}

示例:
情况1: 如果集合中有10个文档,并且serciceDate从2019年6月1日到2019年6月10日。 在我的查询中,我将2019年6月4日传递给2019年6月7日,结果应为null。
情况2: 如果集合中有9个文档,并且serciceDate从2019年6月1日到2019年6月10日,但缺少2019年6月6日。 在我的查询中,我将2019年6月4日传递给2019年6月7日,而结果应该是2019年6月6日。
情况3: 如果集合中有9个文档,并且serciceDate从2019年6月1日到2019年6月10日,但是2019年6月6日,则缺少2019年6月5日。 在我的查询中,我将2019年6月4日传递给2019年6月7日,结果应该是2019年6月6日和2019年6月5日。

1 个答案:

答案 0 :(得分:3)

您需要首先查找查询中传递的日期范围之间的所有日期。与某些JavaScript技巧有关。

function getDates(startDate, stopDate) {
  var dateArray = []
  var currentDate = moment(startDate)
  var stopDate = moment(stopDate)
  while (currentDate <= stopDate) {
    dateArray.push(moment(currentDate).format('YYYY-MM-DD'))
    currentDate = moment(currentDate).add(1, 'days')
  }
  return dateArray
}

const dateArray = getDates(startDate, startDate)

//Output will be something like
dateArray = [ "2018-09-01", "2018-09-02", "2018-09-03", "2018-09-04", "2018-09-05" ]

现在,您可以使用聚合查找$setDifference来获取不存在的serviceDates

db.collection.aggregate([
  { '$match': {
    'serviceDate': { '$gte': startDate, '$lte': endDate }   
  }},
  { '$group': {
    '_id': null,
    'dates': { '$push': { '$dateToString': { 'date': '$serviceDate', 'format': '%Y-%m-%d' }}}
  }},
  { '$project': {
    'missingDates': { '$setDifference': [dateArray, '$dates'] }
  }}
])