Найти пропущенные даты из диапазона дат в MongoDB - PullRequest
3 голосов
/ 31 мая 2019

У меня есть collection, который содержит поле serviceDate для конкретной операции. Мне нужно найти для данного диапазона дат, есть ли какой-либо serviceDate, который отсутствует, и, если он найден, отсутствует список возврата serviceDate dates между диапазоном дат в MongoDB. Пример 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 начинается с 1 июня 2019 года по 10 июня 2019 года. В моем запросе я передаю 4 июня 2019 года на 7 июня 2019 года, тогда результат должен быть нулевым.
Дело 2: Если в коллекции имеется 9 документов и serciceDate, начиная с 1 июня 2019 года по 10 июня 2019 года, но 6 июня 2019 года отсутствует. В моем запросе я передаю 4 июня 2019 года на 7 июня 2019 года, а результат должен быть 6 июня 2019 года.
Дело 3: Если в коллекции 9 документов и serciceDate, начиная с 1 июня 2019 года по 10 июня 2019 года, но 6 июня 2019 года, 5 июня 2019 года отсутствует. В моем запросе я передаю 4 июня 2019 года на 7 июня 2019 года, а результат должен быть 6 июня 2019 года и 5 июня 2019 года.

1 Ответ

3 голосов
/ 31 мая 2019

Сначала необходимо найти все даты между диапазоном дат, который вы передаете в запросе.Что вы должны сделать с некоторыми трюками 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'] }
  }}
])
...