Introducción
FIELDNOTE ha acordado qué cadenas heredadas de recuento representan números fiables. Ahora necesita un catálogo utilizable que conserve esos significados y rechace escrituras futuras inciertas. Un validador por sí solo no limpia registros existentes y convertir todos los valores puede destruir distinciones útiles o inventar recuentos.
Pondrás en cuarentena los originales inciertos, convertirás solo cadenas escalares aprobadas y añadirás un validador real de MongoDB. También crearás y actualizarás un kit válido ordinario para que la tienda pueda seguir trabajando. Completa primero Clasificar y poner en cuarentena registros de equipamiento: aquí se usan su política de documentos, script de conservación de originales, sintaxis de terminal y archivos y distinciones BSON. Esta unidad comienza de forma independiente con un catálogo mixto nuevo y copias de los dos archivos fuente completados. No se requieren archivos, datos ni procesos en ejecución del entorno anterior. Usa Terminal durante todo el laboratorio; MongoDB y el intérprete están preparados. La duración es una estimación del autor.
Crea repair.js y enforce.js en /home/labex/project/catalog-desk. Puedes inspeccionar y conservar los archivos proporcionados policy.js y quarantine.js; las implementaciones equivalentes de política y migración deben cumplir el mismo contrato. Conserva todos los ID originales, los campos ajenos a la tarea, los tipos int/long originales, los originales inciertos completos en cuarentena, las identidades de colecciones y las herramientas proporcionadas. Solo las cadenas aprobadas de stock.available pueden convertirse en recuentos enteros. Añade KIT-901 como se indica y redúcelo una vez; KIT-902, rechazado, no debe existir. No elimines ni reconstruyas colecciones, reemplaces recuentos desconocidos por cero, sobrescribas originales archivados ni impongas reglas que excluyan campos adicionales legítimos. El trabajo es secuencial, sin escritores concurrentes, y no proporciona una transacción para toda la migración.
Convertir solo cadenas de recuento aprobadas
En este paso, eliminarás registros inciertos mediante el flujo de conservación de originales y convertirás solo las representaciones de cadena acordadas. Empieza en Terminal. Entra en el espacio de trabajo preparado de esta unidad:
cd /home/labex/project/catalog-desk
Lee un registro normal e inspecciona los tipos del catálogo nuevo:
./catalog show KIT-101
./catalog types
Los datos iniciales vuelven a ser mixtos: KIT-101 tiene Int32 12, KIT-102 tiene un cero Long, KIT-103/KIT-104 tienen cadenas aprobadas y de KIT-105 a KIT-111 necesitan revisión. Esta es una unidad independiente, por lo que la migración correcta de la unidad anterior no se ha copiado a la base de datos.
cat sin redirección imprime un archivo guardado en lugar de cambiarlo. Inspecciona la política y el script de cuarentena proporcionados de la unidad guiada anterior:
cat policy.js
cat quarantine.js
El selector valid acepta ID y nombres de cadena no vacíos y recuentos escalares BSON int/long de 0 a 50. repairable acepta la misma forma con solo cadenas decimales canónicas en ese intervalo. bad selecciona lo que no cumple ninguno de los dos. El script de cuarentena conserva tipos BSON, retiene documentos originales completos y verifica una copia existente antes de borrar su fuente activa correspondiente. Puede repetirse con seguridad en este escenario controlado y rechaza una copia anterior en conflicto en lugar de sobrescribirla.
Inspecciona los grupos reales y ejecuta después esas fuentes guardadas exactas:
./catalog classify policy.js
./catalog run policy.js quarantine.js
Lee los registros activos restantes y los originales conservados:
./catalog show
./catalog archive
Solo deben seguir activos de KIT-101 a KIT-104. Sus recuentos siguen siendo int, long, string y string respectivamente. De KIT-105 a KIT-111 pertenecen a cuarentena con originales completos, incluidas las distinciones entre ausente, null, array y Double y los campos adicionales de revisión del proveedor. Todavía no se ha adivinado ni convertido ningún recuento.
Ahora guarda un pipeline de actualización. Un documento ordinario de actualización usa operadores de actualización; el array siguiente contiene en cambio etapas de agregación que calculan cada campo modificado a partir del valor actual de ese registro. $set en este pipeline establece el campo indicado y $toInt: "$stock.available" lee el recuento anidado actual y convierte la cadena aprobada a BSON Int32. La cadena que empieza por dólar es una referencia de campo, no texto literal que almacenar. El destino con puntos "stock.available" actualiza solo ese campo anidado, conservando stock.rack y todos los demás campos originales.
updateMany actúa solo sobre registros coincidentes con repairable. Los recuentos int/long existentes válidos no coinciden con ese selector exclusivo de cadenas y conservan sus tipos originales. Sin un filtro correcto, una conversión puede detenerse en un valor no convertible después de haber cambiado registros anteriores; la actualización completa de varios registros no es atómica. Usar onError: 0 u onNull: 0 inventaría un recuento e infringiría esta tarea. Este escenario secuencial preparado no tiene escritores concurrentes.
El here-document REPAIR escribe literalmente el archivo completo, como en la unidad anterior:
cat > repair.js <<'REPAIR'
printjson(db.equipment.updateMany(
repairable,
[{$set: {"stock.available": {$toInt: "$stock.available"}}}]
));
REPAIR
Ejecuta primero la política para que sus nombres de selector estén disponibles, seguida de tu actualización guardada:
./catalog run policy.js repair.js
Busca matchedCount: 2 y modifiedCount: 2. Comprueba los documentos y tipos reales, porque un recuento de modificados por sí solo no demuestra conservación:
./catalog show
./catalog types
KIT-103 tiene ahora Int32 12 y KIT-104 tiene un cero Int32. KIT-102 debe seguir teniendo su cero long original. Se conservan todos los nombres, ubicaciones, campos de proveedor e ID originales. Inspecciona la clasificación restante:
./catalog classify policy.js
Los cuatro registros activos deben estar en valid; ambos grupos restantes deben estar vacíos. Observa por qué fue necesaria la cuarentena antes de esta auditoría: convertir por sí solo no eliminaría valores null, ausentes o inciertos.
Repite la conversión aprobada:
./catalog run policy.js repair.js
Los dos contadores de registros coincidentes y modificados deben ser ahora cero porque no quedan cadenas aprobadas por convertir; las cantidades de existencias no se ponen a cero. Es una conversión idempotente; no significa que todos los posibles errores de base de datos revirtieran automáticamente registros anteriores. Si el archivo tiene un error de sintaxis, reescribe el here-document completo y vuelve a ejecutarlo. Si un nombre de archivo es incorrecto, usa ls y corrígelo; conserva la base de datos existente en lugar de reiniciarla.
Imponer reglas a las escrituras futuras y mantener utilizable el trabajo ordinario
En este paso, aplicarás el contrato aceptado de documentos a escrituras nativas futuras de MongoDB y demostrarás que la tienda todavía puede crear y actualizar un kit válido. Empieza en Terminal, en /home/labex/project/catalog-desk.
El comando collMod de MongoDB cambia opciones de una colección existente. Aquí adjunta el mismo selector valid como validador. validationLevel: "strict" valida inserciones y actualizaciones, incluida la actualización de un registro que ya era no válido. validationAction: "error" rechaza una escritura infractora. moderate puede eximir actualizaciones de registros ya no válidos; warn puede permitir una escritura infractora registrándola en el log. Ninguno cumple el contrato estricto de escrituras futuras requerido aquí.
Adjuntar un validador no es limpieza retroactiva: collMod puede tener éxito mientras quedan registros existentes no válidos. Por eso primero pusiste en cuarentena originales inciertos, convertiste solo cadenas aprobadas y auditaste el catálogo activo. Una respuesta correcta del comando demuestra que cambió la opción; una escritura real aceptada o rechazada demuestra lo que hace.
Guarda el comando nativo. db.runCommand lo ejecuta sobre la base de datos actual del curso y printjson muestra su respuesta real:
cat > enforce.js <<'ENFORCE'
printjson(db.runCommand({
collMod: "equipment",
validator: valid,
validationLevel: "strict",
validationAction: "error"
}));
ENFORCE
Ejecuta la política y este archivo nuevo sin cambios:
./catalog run policy.js enforce.js
Deberías ver ok: 1. Lee las opciones reales de la colección:
./catalog status
La salida debe incluir el validador de equipment con validationLevel: "strict" y validationAction: "error". Este lector también informa de las versiones reales de servidor e intérprete y de la base de datos seleccionada; no genera por ti un resultado correcto de validación.
Prueba una inserción futura incierta con la conexión ordinaria de escritura. invalid-text envía un kit real cuyo recuento es "12 kits". Espera una salida distinta de cero y Document failed validation, no un error de conexión:
./catalog invalid-text KIT-902
Confirma que no se conservó ningún registro nuevo parcial:
./catalog show KIT-902
El resultado debe ser []. La escritura rechazada no convirtió el texto desconocido en cero ni creó un registro sustitutivo en cuarentena. Las escrituras futuras no válidas se rechazan; los registros de cuarentena documentan los datos heredados anteriores.
Ahora crea un kit nuevo legítimo. new ID COUNT envía un documento con un recuento Int32, una ubicación y campos de proveedor. Usa el ID nuevo acordado KIT-901 y un recuento inicial de 4:
./catalog new KIT-901 4
Busca una inserción reconocida de KIT-901. Deben permitirse sus campos adicionales de ubicación y proveedor. use ID COUNT realiza una actualización condicional real: reduce el recuento disponible solo si ese registro tiene suficientes unidades. Usa una unidad:
./catalog use KIT-901 1
Deberías ver matchedCount: 1 y modifiedCount: 1. Lee el resultado real:
./catalog show KIT-901
KIT-901 debe conservar su name, ubicación NEW y proveedor LOCAL, con Int32 3 disponibles. Los cuatro registros originales limpios y todos los originales en cuarentena deben permanecer sin cambios. Un contrato estricto de enteros sigue permitiendo el cero conocido, el límite superior inclusivo, los recuentos long existentes, los campos ajenos a la tarea y las actualizaciones ordinarias válidas.
No repitas el comando new después de que tenga éxito: el _id único produciría un error de clave duplicada. No repitas use salvo que quieras otra reducción. El script guardado de reparación tiene un predicado idempotente exclusivo de cadenas; una acción ordinaria de consumo de existencias cambia intencionadamente el estado de negocio cada vez. Si reduces KIT-901 otra vez por accidente, la tarea permite restaurar únicamente este kit nuevo al recuento final requerido. Usa una pequeña actualización nativa guardada con la misma sintaxis here-document e inspecciónala después. Int32(3) construye explícitamente un entero BSON de 32 bits con valor 3:
cat > restore-new-kit.js <<'RESTORE'
printjson(db.equipment.updateOne({_id: "KIT-901"}, {$set: {"stock.available": Int32(3)}}));
RESTORE
./catalog run restore-new-kit.js
./catalog show KIT-901
Esta recuperación apunta solo a tu kit nuevo y debe dejar el recuento final requerido en 3. No es un método de recuperación para sobrescribir originales heredados ni en cuarentena. Tus archivos reutilizables de política, cuarentena, reparación y aplicación de reglas expresan ahora la migración controlada completa, mientras el catálogo real demuestra que sigue siendo posible el trabajo normal válido.
Resumen
Convertiste cadenas de recuento aprobadas sin reemplazar otros campos anidados ni cambiar tipos numéricos ya válidos. Auditaste el catálogo limpio, impusiste su contrato con validación strict/error, observaste un rechazo real de escritura no válida y completaste una inserción y actualización normales válidas. Los scripts guardados y los originales conservados permiten un flujo de mantenimiento controlado y repetible; no afirman una migración atómica de todo el catálogo ni seguridad ante escritores concurrentes.



