es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Mongo Aggregation $subtract: Siempre da como resultado null cuando se usan dos fechas no vacías.

Quiero obtener una lista de empleados en una secuencia de sus aniversarios laborales. La fecha de ingreso está disponible en los registros de los empleados. En esta consulta, primero se calcula la fecha de aniversario para este año y luego se intenta encontrar la diferencia entre la fecha de hoy y la fecha de aniversario. Pero $subtract devuelve falso para todos los conjuntos de registros.

db.employees.aggregate([{
    "$match": { "deleted": false }
},
{
    "$project": {
        "id": 1, "firstName": 1, "lastName": 1, "empId": 1, "joiningDate": 1,
        "aniversaryDate":
            {
                "$dateFromParts":
                    {
                        "year": { "$year": "$$NOW" },
                        "day": { "$dayOfMonth": "$joiningDate" },
                        "month": { "$month": "$joiningDate" }
                    }
            },
        "dateDifference":
            { "$subtract": ["$aniversaryDate", "$$NOW"] }
    }
},
{ "$sort": { "dateDifference": 1 } }]);

El resultado devuelve un array de objetos similares:

{
    "_id" : ObjectId("61a4bf6b5362437b668db2b5"),
    "empId" : "1",
    "firstName" : "Olive",
    "lastName" : "Gunter",
    "joiningDate" : ISODate("2021-10-03T16:16:58.997+05:30"),
    "aniversaryDate" : ISODate("2021-10-03T05:30:00.000+05:30"),
    "dayssince" : null,
    "dateDifference" : null
}
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para obtener una lista de empleados en secuencia de sus aniversarios de trabajo, necesitamos calcular la próxima fecha de aniversario para cada empleado y luego encontrar la diferencia entre la fecha de hoy y la fecha de aniversario.

    En la consulta dada, podemos ver que estamos usando el operador $dateFromParts para construir la fecha de aniversario para cada empleado. Estamos usando el año actual para obtener el año de la fecha de aniversario, y el mes y el día de la fecha de ingreso para obtener el mes y el día de la fecha de aniversario.

    El siguiente paso es calcular la diferencia entre la fecha de aniversario y la fecha actual usando el operador $subtract. Sin embargo, el operador $subtract no está devolviendo los resultados esperados. Esto se debe a que el operador $subtract requiere que sus argumentos sean valores numéricos, y ISODate no es un valor numérico.

    Para solucionar este problema, necesitamos usar el operador $dateToParts para convertir la fecha de aniversario y la fecha actual en valores numéricos. Luego podemos usar el operador $subtract para encontrar la diferencia entre las dos fechas. Aquí está la consulta actualizada:

    db.employees.aggregate([
      {
        "$match": { "deleted": false }
      },
      {
        "$project": {
          "id": 1,
          "firstName": 1,
          "lastName": 1,
          "empId": 1,
          "joiningDate": 1,
          "aniversaryDate": {
            "$dateFromParts": {
              "year": { "$year": "$$NOW" },
              "month": { "$month": "$joiningDate" },
              "day": { "$dayOfMonth": "$joiningDate" }
            }
          },
          "daysSince": {
            "$subtract": [
              { "$dateToParts": "$$NOW" },
              { "$dateToParts": "$aniversaryDate" }
            ]
          }
        }
      },
      { "$sort": { "daysSince": 1 } }
    ]);
    

    En esta consulta actualizada, estamos usando el operador $dateToParts para convertir la fecha actual ($$NOW) y la fecha de aniversario ($aniversaryDate) en valores numéricos. Luego usamos el operador $subtract para encontrar la diferencia entre las dos fechas.

    Tenga en cuenta que también hemos cambiado el nombre del campo dateDifference a daysSince, ya que este campo ahora representa el número de días desde el último aniversario de trabajo.

    Con estos cambios, la consulta ahora debería devolver una lista de empleados ordenados por el número de días desde su último aniversario de trabajo.

Comments are closed.