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.

Encontrar el Conteo de Fallas Consecutivas en Mongodb.

Tengo un conjunto de datos como este:

{
ip: 1.1.1.1,
proceso: 123,
tipo: falla,
fecha: 2021-04-01
},
{
ip: 1.1.1.2,
proceso: 124,
tipo: falla,
fecha: 2021-03-01
},
{
ip: 1.1.1.1,
proceso: 123,
tipo: falla,
fecha: 2021-02-01
},
{
ip: 1.1.1.1,
proceso: 123,
tipo: éxito,
fecha: 2021-01-01
}

¿Cómo puedo obtener el recuento consecutivo de fallas para una dirección IP y proceso determinados? Por ejemplo, dado el conjunto de datos anterior, si quisiera verificar cuántas veces la dirección IP 1.1.1.1 ha fallado para el proceso 123 antes del último éxito, debería obtener 2. Sin embargo, si el registro de éxito fue el último registro, debería obtener 0.

Lo que tengo hasta ahora es:

activityLog.find([
{
$match: {
ip: "1.1.1.1",
proceso: "123"
},
},
{
$sort: {
fecha: -1,
},
},
{
$limit: 10,
},
{
$project: {
_id: 0,
tipo: 1,
},
},
]);

Esto me da una lista de todos los tipos: ordenados y coincidentes.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para obtener el conteo consecutivo de fallos para una dirección IP y un proceso dados, se puede utilizar el marco de agregación de MongoDB:

    1. $match los registros con la dirección IP y el proceso dados.
    2. $sort los registros por fecha en orden descendente.
    3. $group los registros por el campo type y crear dos arrays – failure y success – que contengan las correspondientes fechas.
    4. Calcular el conteo consecutivo de fallos utilizando el operador $reduce:
    • $zip los arrays de failure y success para obtener pares de fechas consecutivas.
    • $map sobre los pares y verificar si la diferencia entre las fechas es mayor a 1 día (u otra duración). Si lo es, restablecer el conteo consecutivo de fallos a 0, de lo contrario incrementarlo.
    • $max el conteo consecutivo de fallos para obtener el valor máximo.
    1. Devolver el conteo consecutivo máximo de fallos para los fallos, o 0 si el último registro es un éxito.

    Aquí está el código para implementar la lógica anterior:

    const IP_ADDRESS = "1.1.1.1";
    const PROCESS = 123;
    const ONE_DAY_IN_MILLISECONDS = 86400000;
    
    activityLog.aggregate([
      { $match: { ip: IP_ADDRESS, process: PROCESS } },
      { $sort: { date: -1 } },
      {
        $group: {
          _id: "$type",
          dates: { $push: "$date" }
        }
      },
      {
        $project: {
          count: {
            $reduce: {
              input: {
                $zip: {
                  inputs: ["$dates.failure", "$dates.success"]
                }
              },
              initialValue: 0,
              in: {
                $let: {
                  vars: {
                    diffInDays: {
                      $divide: [
                        { $subtract: ["$$value", "$$this.0"] },
                        ONE_DAY_IN_MILLISECONDS
                      ]
                    }
                  },
                  in: {
                    $cond: {
                      if: { $gte: ["$$diffInDays", 1] },
                      then: 0,
                      else: { $add: ["$$value", 1] }
                    }
                  }
                }
              }
            }
          }
        }
      },
      {
        $project: {
          maxConsecutiveFailures: {
            $cond: [
              { $eq: ["$_id", "failure"] },
              { $max: "$count" },
              0
            ]
          }
        }
      }
    ]);
    

    Reemplace IP_ADDRESS y PROCESS con los valores reales que desee verificar. El código devuelve una matriz de objetos que contienen el conteo máximo consecutivo de fallos para los fallos, o 0 si el último registro es un éxito.

Comments are closed.