Introdução
A FIELDNOTE definiu quais strings herdadas de contagem representam números confiáveis. Agora precisa de um catálogo utilizável que preserve esses significados e recuse escritas futuras incertas. Um validador sozinho não limpa registros existentes, e converter todos os valores pode destruir distinções úteis ou inventar contagens.
Você colocará originais incertos em quarentena, converterá apenas strings escalares aprovadas e adicionará um validador real do MongoDB. Também criará e atualizará um kit comum válido para que a loja possa continuar trabalhando. Conclua primeiro Classificar e colocar registros de equipamentos em quarentena: sua política de documentos, script de preservação de originais, sintaxe de terminal/arquivos e distinções BSON são usados aqui. Esta unidade começa independentemente com um novo catálogo misto e cópias dos dois arquivos de fonte concluídos. Nenhum arquivo, dado ou processo em execução do ambiente anterior é necessário. Use Terminal durante todo o lab; o MongoDB e o shell estão preparados. A duração é uma estimativa do autor.
Crie repair.js e enforce.js em /home/labex/project/catalog-desk. Você pode inspecionar e manter os arquivos fornecidos policy.js e quarantine.js; implementações equivalentes de política/migração devem respeitar o mesmo contrato. Preserve todos os IDs originais, campos não relacionados, tipos int/long originais, originais incertos completos em quarentena, identidades das coleções e ferramentas fornecidas. Apenas strings aprovadas em stock.available podem se tornar contagens inteiras. Adicione KIT-901 conforme especificado e decremente-o uma vez; o KIT-902 recusado não deve existir. Não exclua/reconstrua coleções, não substitua contagens desconhecidas por zero, não sobrescreva originais arquivados nem restrinja campos extras legítimos. O trabalho é sequencial sem gravadores concorrentes e não fornece uma transação para toda a migração.
Converter apenas strings aprovadas de contagem
Nesta etapa, você removerá registros incertos pelo fluxo de preservação de originais e converterá apenas as representações de string acordadas. Comece em Terminal. Entre no espaço de trabalho preparado desta unidade:
cd /home/labex/project/catalog-desk
Consulte um registro normal e inspecione os tipos do novo catálogo:
./catalog show KIT-101
./catalog types
Os dados iniciais estão misturados novamente: KIT-101 tem Int32 12, KIT-102 tem Long zero, KIT-103/KIT-104 têm strings aprovadas, e KIT-105 a KIT-111 precisam de revisão. Esta é uma unidade independente, portanto a migração bem-sucedida da unidade anterior não foi copiada para o banco de dados.
cat sem redirecionamento exibe um arquivo salvo em vez de alterá-lo. Inspecione a política e o script de quarentena fornecidos da unidade guiada anterior:
cat policy.js
cat quarantine.js
O seletor valid aceita IDs/nomes como strings não vazias e contagens escalares BSON int/long de 0 a 50. repairable aceita a mesma estrutura apenas com strings decimais canônicas nesse intervalo. bad seleciona os que não atendem a nenhum deles. O script de quarentena preserva tipos BSON, mantém documentos originais completos e verifica uma cópia existente antes de excluir sua origem ativa correspondente. É seguro reexecutá-lo neste cenário controlado, e ele recusa uma cópia antiga conflitante em vez de sobrescrevê-la.
Inspecione os grupos reais e execute exatamente essas fontes salvas:
./catalog classify policy.js
./catalog run policy.js quarantine.js
Consulte os registros ativos restantes e os originais preservados:
./catalog show
./catalog archive
Apenas KIT-101 a KIT-104 devem permanecer ativos. Suas contagens ainda são int, long, string e string, respectivamente. KIT-105 a KIT-111 pertencem à quarentena com originais completos, incluindo distinções entre ausente/null/array/Double e os campos extras de revisão com o fornecedor. Nenhuma contagem foi adivinhada nem convertida ainda.
Agora salve um pipeline de atualização. Um documento comum de atualização usa operadores de atualização; o array abaixo contém, em vez disso, estágios de agregação que calculam cada campo alterado a partir do valor atual desse registro. $set neste pipeline define o campo nomeado, e $toInt: "$stock.available" lê a contagem aninhada atual e converte a string aprovada em BSON Int32. A string prefixada por cifrão é uma referência de campo, não texto literal a armazenar. O destino com ponto "stock.available" atualiza apenas esse campo aninhado, mantendo stock.rack e todos os outros campos originais.
updateMany atua apenas nos registros correspondentes a repairable. Contagens int/long válidas existentes não correspondem a esse seletor exclusivo de strings e mantêm seus tipos originais. Sem um filtro correto, uma conversão pode parar em um valor não convertível depois de registros anteriores terem mudado; a atualização inteira de vários registros não é atômica. Usar onError: 0 ou onNull: 0 inventaria uma contagem e violaria esta tarefa. Este cenário sequencial preparado não tem gravadores concorrentes.
O here-document REPAIR grava o arquivo completo literalmente, como na unidade anterior:
cat > repair.js <<'REPAIR'
printjson(db.equipment.updateMany(
repairable,
[{$set: {"stock.available": {$toInt: "$stock.available"}}}]
));
REPAIR
Execute primeiro a política para que os nomes dos seletores estejam no escopo, seguida de sua atualização salva:
./catalog run policy.js repair.js
Procure matchedCount: 2 e modifiedCount: 2. Verifique documentos e tipos reais, porque uma contagem de modificações sozinha não comprova preservação:
./catalog show
./catalog types
KIT-103 agora tem Int32 12, e KIT-104 tem Int32 zero. KIT-102 ainda deve ter seu zero long original. Todos os nomes, posições nas estantes, campos de fornecedor e IDs originais permanecem. Inspecione a classificação restante:
./catalog classify policy.js
Os quatro registros ativos devem estar em valid; os outros dois grupos devem estar vazios. Observe por que a quarentena era necessária antes desta auditoria: a conversão sozinha não removeria valores null, ausentes ou incertos.
Reexecute a conversão aprovada:
./catalog run policy.js repair.js
Os contadores de registros correspondentes e de registros modificados agora devem ser zero porque não restam strings aprovadas; isso não significa definir as quantidades de estoque como zero. Esta é uma conversão idempotente; não significa que todo erro possível do banco de dados desfaria automaticamente registros anteriores. Se o arquivo tiver um erro de sintaxe, reescreva o here-document completo e execute-o novamente. Se um nome de arquivo estiver errado, use ls e corrija-o; mantenha o banco de dados existente em vez de reinicializá-lo.
Validar escritas futuras e manter o trabalho comum utilizável
Nesta etapa, você aplicará o contrato aceito de documentos às escritas nativas futuras do MongoDB e comprovará que a loja ainda consegue criar e atualizar um kit válido. Comece em Terminal, em /home/labex/project/catalog-desk.
O comando collMod do MongoDB altera as opções de uma coleção existente. Aqui, ele associa o mesmo seletor valid como validador. validationLevel: "strict" valida inserções e atualizações, incluindo uma atualização em um registro que já era inválido. validationAction: "error" rejeita uma escrita que viole as regras. moderate pode isentar atualizações em registros já inválidos; warn pode permitir uma escrita que viole as regras enquanto a registra em log. Nenhum deles é o contrato estrito de escritas futuras exigido aqui.
Associar um validador não é limpeza retroativa: collMod pode ter sucesso enquanto registros existentes inválidos permanecem. Por isso, você primeiro colocou originais incertos em quarentena, converteu apenas strings aprovadas e auditou o catálogo ativo. Uma resposta de comando bem-sucedida é evidência de que a opção mudou; uma escrita real aceita/recusada é evidência do que ela faz.
Salve o comando nativo. db.runCommand o executa no banco de dados atual do curso, e printjson exibe sua resposta real:
cat > enforce.js <<'ENFORCE'
printjson(db.runCommand({
collMod: "equipment",
validator: valid,
validationLevel: "strict",
validationAction: "error"
}));
ENFORCE
Execute a política e este novo arquivo sem alterações:
./catalog run policy.js enforce.js
Espere ok: 1. Consulte as opções reais da coleção:
./catalog status
A saída deve incluir o validador de equipment com validationLevel: "strict" e validationAction: "error". Este leitor também informa as versões reais do servidor/shell e o banco de dados selecionado; não gera um resultado bem-sucedido de validação por você.
Tente uma inserção futura incerta com a conexão comum de escrita. invalid-text envia um kit real cuja contagem é "12 kits". Espere um status de saída diferente de zero e Document failed validation, não um erro de conexão:
./catalog invalid-text KIT-902
Confirme que nenhum novo registro parcial foi mantido:
./catalog show KIT-902
O resultado deve ser []. A escrita rejeitada não transformou o texto desconhecido em zero nem criou um registro substituto de quarentena. Escritas futuras inválidas são recusadas; os registros de quarentena documentam os dados herdados anteriores.
Agora crie um novo kit legítimo. new ID COUNT envia um documento com contagem Int32, posição na estante e campos de fornecedor. Use o novo ID acordado KIT-901 e uma contagem inicial de 4:
./catalog new KIT-901 4
Procure uma inserção reconhecida de KIT-901. Seus campos extras de posição na estante/fornecedor devem ser permitidos. use ID COUNT executa uma atualização condicional real: decrementa a contagem disponível apenas quando esse registro tem unidades suficientes. Use uma unidade:
./catalog use KIT-901 1
Espere matchedCount: 1 e modifiedCount: 1. Consulte o resultado real:
./catalog show KIT-901
KIT-901 deve manter seu name, a posição NEW e o fornecedor LOCAL, com Int32 3 disponíveis. Os quatro registros originais limpos e todos os originais de quarentena devem permanecer inalterados. Um contrato estrito de inteiros ainda permite zero conhecido, o limite superior inclusivo, contagens long existentes, campos não relacionados e atualizações comuns válidas.
Não reexecute o comando new após seu sucesso: o _id único produziria um erro de chave duplicada. Não reexecute use a menos que pretenda outro decremento. O script salvo de reparo tem um predicado idempotente exclusivo de strings; uma ação comum de uso de estoque altera intencionalmente o estado de negócio a cada vez. Se decrementar KIT-901 novamente por engano, a tarefa do curso permite restaurar apenas este novo kit à contagem final exigida. Use uma pequena atualização nativa salva, com a mesma sintaxe de here-document, e inspecione-o depois. Int32(3) constrói explicitamente um inteiro BSON de 32 bits com 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 recuperação se destina apenas ao seu novo kit e deve deixar a contagem final exigida em 3. Não é um método de recuperação para sobrescrever originais herdados ou em quarentena. Seus arquivos reutilizáveis de política, quarentena, reparo e validação agora expressam a migração controlada completa, enquanto o catálogo real demonstra que o trabalho normal válido continua possível.
Resumo
Você converteu strings aprovadas de contagem sem substituir outros campos aninhados nem alterar tipos numéricos já válidos. Auditou o catálogo limpo, impôs seu contrato com validação strict/error, observou uma recusa real de escrita inválida e concluiu uma inserção/atualização normal válida. Os scripts salvos e os originais preservados dão suporte a um fluxo controlado de manutenção repetível; não afirmam migração atômica do catálogo inteiro nem segurança contra gravadores concorrentes.



