Как вычесть две даты и сравнить результат с другим полем? - PullRequest
0 голосов
/ 07 июня 2019

Я довольно новичок в MongoDB.У меня есть коллекция со следующей структурой документа:

{
  "active": true,
  "days": [],
  "start_date": ISODate("..."),
  "end_date": ISODate("..."),
  "frequency": 600000,
  "latest_execution_date": ISODate("...")
} 
{
  "active": false,
  "days": [1, 2, 3],
  "start_date": ISODate("..."),
  "end_date": ISODate("..."),
  "frequency": 600000,
  "latest_execution_date": ISODate("...")
} 
{
  "active": true,
  "days": [2, 5],
  "start_date": ISODate("..."),
  "end_date": ISODate("..."),
  "frequency": 600000,
  "latest_execution_date": ISODate("...")
}

Я хочу найти, активные документы с массивом «days» пустые или текущий день недели находится в массиве, а текущая датамежду "start_date" и "end_date", а разница между "latest_execution_date" и текущей датой больше, чем "частота".

Я создал этот запрос, и он работает для меня, но для сервера MongoDB, который яИспользование больше не поддерживает "$ где".

db.myCollection.find({          
    $where: function() {
        const currentDate = new Date();                
        const latestExecution = new Date(this.latest_execution_date);
        return (
            this.active &&
            this.start_date <= currentDate &&
            this.end_date >= currentDate &&
            (this.days.includes(currentDate.getDay()) || this.days.length === 0) &&
            (this.latest_execution_date === null || ((currentDate.valueOf() - latestExecution.valueOf()) >= this.frequency))
        );
    }
})

Я пытаюсь заменить "найти" на "агрегацию", но я застрял с вычитанием и сравнением, это то, что яесть сейчас, но $ cmp не работает должным образом.

db.myCollection.aggregate([{
    $project: {            
        active: "$active",        
        start_date: "$start_date",
        end_date: "$end_date",
        days: "$days",
        frequency: "$frequency"
        latest_execution_date: "$latest_execution_date",
        dateDifference: {                  
            $subtract: [ new Date(), "$latest_execution_date" ]              
        },
        compare: {
            $cmp: [ "$dateDifference", "$frequency" ]
        }
    }
},
{
    $match: {        
        active:{$eq:true},        
        start_date:{$lte: ISODate("...")},
        end_date:{$gte: ISODate("...")},              
        $and: [
            { $or:[ { days:{$size:0}}, { days:{$elemMatch:{$eq:<day of the week>} } }] },
            { $or: [ { latest_execution_date: { $eq: null } }, { compare: { $lte: 0 } } ] }
        ]       
    }     
}
])

Основная проблема, с которой я сталкиваюсь при таком подходе, это "$ cmp", который всегда возвращает "-1", это не такнезависимо от того, является ли «частота» больше или нет.Я проверил типы данных, частота Int32 и dateDifference Int64.Преобразование частоты в Int64 (частота: {$ convert: {input: "$quency", to: "long"}}) Я получил то же самое.

Кто-то знает, как решить эту проблему?или есть другой подход для решения этой проблемы?Все советы, предложения или критика приветствуются.

Спасибо!

1 Ответ

0 голосов
/ 15 июня 2019

Я не успел опубликовать свое решение.Я позволю это здесь в случае, если это кому-то поможет.

db.myCollection.aggregate([{
    $project: {            
        ...
        dateDifference: {                  
           $subtract: [{ $subtract: [new Date(), '$latest_execution_date'] }, '$frequency']            
        }
    }
},
{
    $match: {        
       ...           
       $and: [
         { $or:[ { days:{$size:0}}, { days:{$elemMatch:{$eq:<day of the week>} } }] },
         { $or: [ { latest_execution_date: { $eq: null } }, { dateDifference:{$gte:0}} ] }
        ]       
    }     
}
])

По сути, я понял, что усложняю решение без какой-либо причины, достаточно просто добавить вложенное вычитание, а затем проверить результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...