Tengo una colección llamada "inventory_devices" y de esta necesito sacar los documentos que están cerca de mantenimiento (generalmente 30 días antes de la próxima fecha de mantenimiento) y en este momento estoy tratando de filtrar los documentos que están en el campo "date_close_to_maintenance" “30 días antes de la fecha y no encuentro la forma de hacerlo. "maintenance_next_date" es de tipo Cadena. Actualmente uso la biblioteca Mongoose para consultas MongoDB en NodeJS.
La variable/campo "contrato" es el identificador común que tienen los documentos y es el que me sirve para agruparlos. Cada número X de documentos tiene un contrato asociado, algo así como un "Tipo de cliente" de una tabla de clientes.
El modelo tiene lo siguiente, mostraré los datos que se usan solo porque el modelo podría tomar 300 filas:
const mongoose = require('mongoose') const Schema = mongoose.Schema const InventarioDispositivosSchema = new mongoose.Schema({ contrato: { type: Schema.Types.ObjectId, ref: 'Contrato' }, informacion_equipo: { type: Object, require: ["sistema_operativo", "ip", "nombre_equipo", "usuario_red"], properties: { ususario_red: { //Este campo y el modelo en sí funciona como está type: String, required: false, trim: true, }, }, },fecha_proximo_mantenimiento: { type: String, required: false, trim: true, }, { collection: 'inventario_dispositivos', timestamps: true }) const InventarioDispositivos = mongoose.model('InventarioDispositivos', InventarioDispositivosSchema) module.exports = InventarioDispositivostengo la siguiente consulta:
// With "contrato" burned let contrato = 'contrato1'; Dispositivos.find( { //Filtros que se le hacen a la consulta contrato, fecha_proximo_mantenimiento: { $exists: true } }, { //Datos que quiero que se muestren, solo el ID se oculta. _id: 0, 'informacion_equipo.ususario_red': 1, fecha_proximo_mantenimiento: 1 } ).limit(10).then((devices) => { console.log(devices) }).catch(err => { console.log(err) })Una muestra del modelo que se muestra y lo que devuelve la consulta anterior:
{ informacion_equipo: { ususario_red: 'angel.goez' }, fecha_proximo_mantenimiento: '2021-08-30' }, { informacion_equipo: { ususario_red: 'angel.goez' }, fecha_proximo_mantenimiento: '2021-08-25' }Espero haber entendido bien tu pregunta.
La consulta a continuación filtrará los documentos que tengan fecha_proximo_mantenimiento con valor anterior a 30 días.
[ { "$addFields": { "fecha_proximo_mantenimiento_timestamp": { "$subtract": [ "$$NOW", { "$toDate": "$fecha_proximo_mantenimiento" } ] } } }, { "$match": { "fecha_proximo_mantenimiento_timestamp": { "$gte": 1000 * 60 * 60 * 24 * 30 } } } ] La primera etapa $addFields agrega un nuevo campo (llamé igual que el original con _timestamp adjunto y resta el valor del campo (que también se convierte en Fecha, ya que su esquema lo definió como Cadena) de Fecha.
Verificaciones $match segunda etapa cuyo resultado sustraído (en milisegundos) es mayor a 30 días (también puede reemplazarlo con 2592000000 si le resulta más fácil).
const hasta = moment(new Date()).add(30, 'days').format('YYYY-MM-DD'); const desde = moment(new Date()).format('YYYY-MM-DD'); const contrato= 0; Dispositivos.find( contrato, fecha_proximo_mantenimiento: { $exists: true } }, { _id: 0, 'informacion_equipo.ususario_red': 1, fecha_proximo_mantenimiento: 1 }) .where('fecha_proximo_mantenimiento') .gte(desde) .lte(hasta) .exec(function (err, result) { if (err) { console.log(err) } else { for (var x in result) { console.log('numero de documento: ', x, result[x]) } } });También funciona con find