Validar datos de MongoDB

MongoDBMongoDBBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderá a validar los tipos de datos de MongoDB, manejar datos no válidos y prevenir entradas incorrectas para mantener la integridad de los datos en su base de datos MongoDB. Comenzará explorando los diferentes tipos de datos admitidos por MongoDB y creando una colección de muestra con requisitos de tipo de datos específicos. Luego, practizará insertar documentos con tipos incorrectos y aprenderá cómo insertar correctamente datos que cumplan con los criterios de validación. Al final de este laboratorio, tendrá una sólida comprensión de las técnicas de validación de datos y manejo de errores de MongoDB.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mongodb(("MongoDB")) -.-> mongodb/BasicOperationsGroup(["Basic Operations"]) mongodb(("MongoDB")) -.-> mongodb/QueryOperationsGroup(["Query Operations"]) mongodb(("MongoDB")) -.-> mongodb/DataTypesGroup(["Data Types"]) mongodb(("MongoDB")) -.-> mongodb/ErrorHandlingGroup(["Error Handling"]) mongodb/BasicOperationsGroup -.-> mongodb/create_database_collection("Create Database and Collection") mongodb/BasicOperationsGroup -.-> mongodb/insert_document("Insert Document") mongodb/BasicOperationsGroup -.-> mongodb/update_document("Update Document") mongodb/QueryOperationsGroup -.-> mongodb/find_documents("Find Documents") mongodb/DataTypesGroup -.-> mongodb/use_numeric_data_types("Use Numeric Data Types") mongodb/DataTypesGroup -.-> mongodb/use_string_data_types("Use String Data Types") mongodb/DataTypesGroup -.-> mongodb/work_with_array_data_types("Work with Array Data Types") mongodb/ErrorHandlingGroup -.-> mongodb/handle_write_errors("Handle Write Errors") subgraph Lab Skills mongodb/create_database_collection -.-> lab-422100{{"Validar datos de MongoDB"}} mongodb/insert_document -.-> lab-422100{{"Validar datos de MongoDB"}} mongodb/update_document -.-> lab-422100{{"Validar datos de MongoDB"}} mongodb/find_documents -.-> lab-422100{{"Validar datos de MongoDB"}} mongodb/use_numeric_data_types -.-> lab-422100{{"Validar datos de MongoDB"}} mongodb/use_string_data_types -.-> lab-422100{{"Validar datos de MongoDB"}} mongodb/work_with_array_data_types -.-> lab-422100{{"Validar datos de MongoDB"}} mongodb/handle_write_errors -.-> lab-422100{{"Validar datos de MongoDB"}} end

Comprobar los tipos de datos

En este paso, aprenderá a comprobar y validar los tipos de datos en MongoDB, lo cual es fundamental para mantener la integridad de los datos y prevenir errores en su base de datos.

Comprender los tipos de datos en MongoDB

MongoDB admite varios tipos de datos, incluyendo:

  • String
  • Integer
  • Double
  • Boolean
  • Array
  • Object
  • Date
  • ObjectId
  • Null

Comencemos abriendo la shell de MongoDB y explorando la validación de tipos de datos:

mongosh

Crear una colección de muestra con validación de tipo

Crearemos una colección de usuarios con requisitos de tipo de datos específicos:

use dataValidationLab

db.createCollection("users", {
   validator: {
      $jsonSchema: {
         bsonType: "object",
         required: ["name", "age", "email"],
         properties: {
            name: {
               bsonType: "string",
               description: "debe ser una cadena y es obligatoria"
            },
            age: {
               bsonType: "int",
               minimum: 18,
               maximum: 120,
               description: "debe ser un número entero entre 18 y 120"
            },
            email: {
               bsonType: "string",
               pattern: "^.+@.+$",
               description: "debe ser una dirección de correo electrónico válida"
            }
         }
      }
   }
})

Analicemos la validación:

  • bsonType: "string" asegura que el campo sea una cadena
  • bsonType: "int" asegura que el campo sea un número entero
  • minimum y maximum establecen restricciones de rango
  • pattern valida el formato del correo electrónico

Intentar insertar documentos con tipos incorrectos

Ahora, intentemos insertar documentos para probar nuestra validación:

// Esto fallará debido a un tipo de edad incorrecto
db.users.insertOne({
  name: "John Doe",
  age: "25", // Cadena en lugar de número entero
  email: "[email protected]"
});

// Esto también fallará debido a un correo electrónico no válido
db.users.insertOne({
  name: "Jane Smith",
  age: 30,
  email: "invalid-email"
});

Inserción correcta de documentos

Aquí está cómo insertar un documento válido:

db.users.insertOne({
  name: "Alice Johnson",
  age: NumberInt(28),
  email: "[email protected]"
});

Tenga en cuenta el uso de NumberInt() para crear explícitamente un número entero.

Validar campos obligatorios

En este paso, construiremos sobre nuestro trabajo anterior de validación de datos, centrándonos en garantizar que los campos obligatorios siempre estén presentes en nuestros documentos de MongoDB.

Comprender los campos obligatorios

Los campos obligatorios son piezas esenciales de información que deben estar presentes en cada documento. En el paso anterior, creamos un esquema de validación con campos obligatorios. Ahora, exploraremos cómo hacer cumplir y validar estos requisitos.

Continuemos en la shell de MongoDB:

mongosh

Cambiemos a nuestra base de datos existente:

use dataValidationLab

Definir una validación estricta de campos obligatorios

Modificaremos nuestra colección de usuarios existente para hacer cumplir una validación estricta de campos obligatorios:

db.runCommand({
  collMod: "users",
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "age", "email", "registrationDate"],
      properties: {
        name: {
          bsonType: "string",
          description: "El nombre es obligatorio y debe ser una cadena"
        },
        age: {
          bsonType: "int",
          minimum: 18,
          maximum: 120,
          description:
            "La edad es obligatoria y debe ser un número entero entre 18 y 120"
        },
        email: {
          bsonType: "string",
          pattern: "^.+@.+$",
          description:
            "El correo electrónico es obligatorio y debe ser una dirección de correo electrónico válida"
        },
        registrationDate: {
          bsonType: "date",
          description:
            "La fecha de registro es obligatoria y debe ser una fecha"
        }
      }
    }
  },
  validationLevel: "strict"
});

Intentar insertar documentos con campos faltantes

Intentemos insertar documentos con campos obligatorios faltantes:

// Esto fallará debido a la falta de registrationDate
db.users.insertOne({
  name: "Bob Wilson",
  age: NumberInt(35),
  email: "[email protected]"
});

// Esto también fallará debido a la falta de campos obligatorios
db.users.insertOne({
  name: "Charlie Brown"
});

Inserción correcta de documentos

Aquí está cómo insertar un documento que cumple con todos los requisitos:

db.users.insertOne({
  name: "Emma Thompson",
  age: NumberInt(42),
  email: "[email protected]",
  registrationDate: new Date()
});

Verificar los errores de validación

Para entender por qué las inserciones fallan, MongoDB proporciona mensajes de error de validación:

try {
  db.users.insertOne({
    name: "Incomplete User"
  });
} catch (error) {
  print("Validation Error:", error.message);
}

Esto le ayudará a entender exactamente qué campos obligatorios faltan.

Manejar datos no válidos

En este paso, aprenderemos a manejar y gestionar datos no válidos en MongoDB, centrándonos en la captura de errores, el registro y la implementación de estrategias de validación de datos.

Preparar el entorno

Continuemos en la shell de MongoDB:

mongosh

Cambiemos a nuestra base de datos existente:

use dataValidationLab

Crear una colección de manejo de errores

Crearemos una nueva colección con validación avanzada y manejo de errores:

db.createCollection("products", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "price", "category"],
      properties: {
        name: {
          bsonType: "string",
          minLength: 2,
          maxLength: 100
        },
        price: {
          bsonType: ["double", "int"],
          minimum: 0,
          description: "El precio debe ser un número positivo"
        },
        category: {
          enum: ["Electronics", "Clothing", "Books", "Food"],
          description: "La categoría debe ser uno de los valores predefinidos"
        }
      }
    }
  },
  validationAction: "error"
});

Implementar un mecanismo de manejo de errores

Crearemos una función para manejar inserciones de datos no válidos:

function safeInsertProduct(product) {
  try {
    db.products.insertOne(product);
    print("Producto insertado correctamente:", product.name);
  } catch (error) {
    print("Error al insertar el producto:", error.message);

    // Registrar datos no válidos en una colección separada
    db.invalidProducts.insertOne({
      product: product,
      errorMessage: error.message,
      timestamp: new Date()
    });
  }
}

Probar el manejo de errores

Probemos nuestro manejo de errores con varios escenarios:

// Inserción de producto válido
safeInsertProduct({
  name: "Smartphone",
  price: 599.99,
  category: "Electronics"
});

// Producto no válido - tipo de precio incorrecto
safeInsertProduct({
  name: "Laptop",
  price: "1000", // Cadena en lugar de número
  category: "Electronics"
});

// Producto no válido - categoría no válida
safeInsertProduct({
  name: "T-Shirt",
  price: 29.99,
  category: "Accessories" // No está en las categorías predefinidas
});

// Producto no válido - nombre corto
safeInsertProduct({
  name: "A",
  price: 10,
  category: "Books"
});

Revisar los registros de datos no válidos

Veamos los registros de productos no válidos:

print("Registro de Productos No Válidos:");
db.invalidProducts.find();

Mejores prácticas para el manejo de errores

  1. Siempre validar los datos antes de la inserción
  2. Utilizar bloques try-catch
  3. Registrar datos no válidos para revisión posterior
  4. Implementar la validación a nivel de esquema
  5. Utilizar acciones de validación adecuadas

Corregir problemas de datos

En este paso, aprenderemos técnicas para identificar y corregir problemas de datos en MongoDB, centrándonos en estrategias de limpieza y transformación de datos.

Preparar el entorno

Continuemos en la shell de MongoDB:

mongosh

Cambiemos a nuestra base de datos existente:

use dataValidationLab

Crear una colección de limpieza de datos

Crearemos una colección con datos potencialmente problemáticos:

db.createCollection("customers", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "email", "age"],
      properties: {
        name: {
          bsonType: "string",
          minLength: 2
        },
        email: {
          bsonType: "string",
          pattern: "^.+@.+$"
        },
        age: {
          bsonType: "int",
          minimum: 18,
          maximum: 120
        }
      }
    }
  }
});

// Insertar algunos datos de muestra con posibles problemas
db.customers.insertMany([
  { name: "John Doe", email: "john@example", age: "35" },
  { name: "A", email: "invalid-email", age: 15 },
  { name: "Jane Smith", email: "[email protected]", age: 25 }
]);

Función de limpieza de datos

Crearemos una función para limpiar y validar los datos de los clientes:

function cleanCustomerData() {
  // Encontrar y corregir documentos no válidos
  const invalidCustomers = db.customers.find({
    $or: [
      { age: { $type: "string" } },
      { email: { $not: /^.+@.+$/ } },
      {
        name: { $exists: true, $expr: { $lt: [{ $strLenBytes: "$name" }, 2] } }
      }
    ]
  });

  invalidCustomers.forEach((customer) => {
    // Corregir la edad: convertir a entero
    const fixedAge =
      typeof customer.age === "string"
        ? parseInt(customer.age)
        : customer.age < 18
          ? 18
          : customer.age;

    // Corregir el correo electrónico: agregar dominio si falta
    const fixedEmail = customer.email.includes("@")
      ? customer.email
      : `${customer.email}@example.com`;

    // Corregir el nombre: rellenar nombres cortos
    const fixedName =
      customer.name.length < 2 ? customer.name.padEnd(2, "X") : customer.name;

    // Actualizar el documento con los datos corregidos
    db.customers.updateOne(
      { _id: customer._id },
      {
        $set: {
          age: NumberInt(fixedAge),
          email: fixedEmail,
          name: fixedName
        }
      }
    );

    print(`Cliente corregido: ${customer.name}`);
  });

  // Verificar datos limpios
  print("Verificación de datos limpios:");
  db.customers.find().forEach(printjson);
}

// Ejecutar la función de limpieza
cleanCustomerData();

Validación de datos después de la limpieza

Verifiquemos que los datos limpios cumplan con nuestros criterios de validación:

function validateCustomers() {
  const invalidCustomersCount = db.customers
    .find({
      $or: [
        { age: { $not: { $type: "int" } } },
        { age: { $lt: 18, $gt: 120 } },
        { email: { $not: /^.+@.+$/ } },
        {
          name: {
            $exists: true,
            $expr: { $lt: [{ $strLenBytes: "$name" }, 2] }
          }
        }
      ]
    })
    .count();

  print(`Número de clientes no válidos restantes: ${invalidCustomersCount}`);
  return invalidCustomersCount === 0;
}

validateCustomers();

Mejores prácticas para la corrección de datos

  1. Siempre validar antes y después de la transformación de datos
  2. Utilizar la conversión de tipos con cuidado
  3. Establecer valores predeterminados o mínimos para campos críticos
  4. Registrar los cambios de datos para auditoría
  5. Crear una copia de seguridad antes de la limpieza masiva de datos

Prevenir entradas incorrectas

En este último paso, exploraremos técnicas avanzadas para prevenir entradas incorrectas y mejorar la integridad de los datos en MongoDB a través de estrategias de validación exhaustivas.

Preparar el entorno

Continuemos en la shell de MongoDB:

mongosh

Cambiemos a nuestra base de datos existente:

use dataValidationLab

Crear un esquema de validación robusto

Crearemos un esquema de validación exhaustivo para una colección'registrations':

db.createCollection("registrations", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["username", "email", "password", "registrationDate"],
      properties: {
        username: {
          bsonType: "string",
          minLength: 3,
          maxLength: 20,
          pattern: "^[a-zA-Z0-9_]+$",
          description:
            "El nombre de usuario debe ser alfanumérico, de 3 a 20 caracteres"
        },
        email: {
          bsonType: "string",
          pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
          description: "Debe ser una dirección de correo electrónico válida"
        },
        password: {
          bsonType: "string",
          minLength: 8,
          description: "La contraseña debe tener al menos 8 caracteres",
          pattern:
            "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,}$"
        },
        registrationDate: {
          bsonType: "date",
          description: "La fecha de registro debe ser una fecha válida"
        }
      }
    }
  },
  validationAction: "error",
  validationLevel: "strict"
});

Implementar middleware de prevención de entrada

Crea una función para validar la entrada antes de la inserción:

function safeRegister(userData) {
  // Limpiar y validar la entrada
  const sanitizedData = {
    username: userData.username.trim().toLowerCase(),
    email: userData.email.trim().toLowerCase(),
    password: userData.password,
    registrationDate: new Date()
  };

  // Validaciones personalizadas adicionales
  if (sanitizedData.username.length < 3) {
    throw new Error("El nombre de usuario es demasiado corto");
  }

  if (db.registrations.findOne({ username: sanitizedData.username })) {
    throw new Error("El nombre de usuario ya existe");
  }

  if (db.registrations.findOne({ email: sanitizedData.email })) {
    throw new Error("El correo electrónico ya está registrado");
  }

  try {
    // Intentar insertar con validación de MongoDB
    db.registrations.insertOne(sanitizedData);
    print("Registro exitoso:", sanitizedData.username);
  } catch (error) {
    print("Registro fallido:", error.message);

    // Registrar intentos de registro fallidos
    db.registrationAttempts.insertOne({
      attemptData: userData,
      errorMessage: error.message,
      timestamp: new Date()
    });
  }
}

// Probar la prevención de entrada
function testRegistrations() {
  const testCases = [
    // Registro válido
    {
      username: "john_doe",
      email: "[email protected]",
      password: "Strong!Pass123"
    },

    // Casos no válidos
    { username: "ab", email: "invalid-email", password: "short" },
    { username: "john_doe!", email: "[email protected]", password: "WeakPass" },
    {
      username: "special_chars!",
      email: "invalid@email",
      password: "NoSpecialChar123"
    }
  ];

  testCases.forEach((testCase) => {
    print("\nProbando registro:");
    printjson(testCase);
    safeRegister(testCase);
  });
}

// Ejecutar las pruebas de registro
testRegistrations();

Revisar los intentos de registro

Verifica los intentos de registro registrados:

print("Intentos de registro fallidos:");
db.registrationAttempts.find();

Mejores prácticas para la prevención de entrada

  1. Utilizar validación de esquema exhaustiva
  2. Implementar la limpieza de entrada en el servidor
  3. Utilizar patrones de expresiones regulares para validación estricta
  4. Registrar y rastrear intentos de entrada no válidos
  5. Implementar lógica de validación personalizada adicional

Resumen

En este laboratorio, aprendiste a verificar y validar los tipos de datos en MongoDB para mantener la integridad de los datos y prevenir errores en tu base de datos. Exploraste los diversos tipos de datos admitidos por MongoDB, incluyendo cadena, entero, doble, booleano, matriz, objeto, fecha, ObjectId y nulo. Creaste una colección de usuarios de muestra con requisitos específicos de tipo de datos, como asegurarte de que el nombre sea una cadena, la edad sea un número entero entre 18 y 120 y el correo electrónico sea una dirección de correo electrónico válida. También aprendiste a manejar datos no válidos al intentar insertar documentos con tipos incorrectos y a entender los mensajes de error.

Finalmente, practicaste insertar documentos con los tipos de datos correctos para agregarlos con éxito a la colección de usuarios.