介绍
FIELDNOTE 已约定哪些接手的数量字符串表示可靠数字。现在需要可用商品目录,保留这些含义,并拒绝未来的不确定写入。仅添加校验器不会清理已有记录,而转换所有值可能破坏有用区别或编造数量。
你将隔离不确定原件,只转换批准的标量字符串,并添加真实 MongoDB 校验器。你还将创建并更新普通有效套件,让店铺继续工作。先完成设备记录分类与隔离:本单元会使用其中的文档策略、原件保留脚本、终端与文件语法及 BSON 区别。本单元独立从全新混合商品目录和两个已完成源文件副本开始,不需要上一环境的文件、数据或运行进程。全程使用 Terminal;MongoDB 和 shell 已准备好。时长为作者估计。
在 /home/labex/project/catalog-desk 创建 repair.js 和 enforce.js。可以检查并保留提供的 policy.js 和 quarantine.js;等效策略或迁移实现必须满足相同契约。保留全部原始 ID、无关字段、原始 int/long 类型、隔离区完整不确定原件、集合标识及提供的工具。只有 stock.available 中批准的字符串可以转为整数数量。按要求添加 KIT-901 并扣减一次;被拒绝的 KIT-902 不得存在。不要删除重建集合、把未知数量改成零、覆盖归档原件,或收紧规则排除合法额外字段。工作顺序执行,没有并发写入方,不提供覆盖整个迁移的事务。
只转换批准的数量字符串
本步骤中,你将通过保留原件的流程移除不确定记录,并只转换约定字符串表示。从 Terminal 开始,进入本单元预备工作区:
cd /home/labex/project/catalog-desk
读取普通记录,检查全新商品目录类型:
./catalog show KIT-101
./catalog types
初始数据再次混合:KIT-101 是 Int32 12,KIT-102 是 Long 零值,KIT-103/KIT-104 是批准字符串,KIT-105 到 KIT-111 需要审核。本单元独立运行,上一单元成功迁移的结果并未复制到数据库。
不带重定向的 cat 打印保存文件,而不修改它。检查提供的上一引导单元策略和隔离脚本:
cat policy.js
cat quarantine.js
valid 选择器接受非空字符串 ID 和名称,以及 0 到 50 的 BSON int/long 标量数量。repairable 接受相同形状,但数量只能是该范围的规范十进制字符串。bad 选择两者都不匹配的记录。隔离脚本保留 BSON 类型和完整原始文档,在删除对应活跃源记录前验证已有副本。在本受控场景中可以安全重跑;它会拒绝冲突旧副本,而不是覆盖它。
检查实际分组,再运行这些确切的保存源文件:
./catalog classify policy.js
./catalog run policy.js quarantine.js
读取剩余活跃记录及保留原件:
./catalog show
./catalog archive
活跃集合应只剩 KIT-101 到 KIT-104,数量类型依次仍为 int、long、string、string。KIT-105 到 KIT-111 位于隔离区,保留完整原件,包括缺失、null、数组、Double 的区别,以及额外供应商审核字段。尚未猜测或转换任何数量。
现在保存更新管道。普通更新文档使用更新运算符;下面的数组则包含聚合阶段,根据各记录当前值计算被修改字段。此管道中的 $set 设置指定字段,$toInt: "$stock.available" 读取当前嵌套数量,并将批准字符串转为 BSON Int32。以美元符号开头的字符串是字段引用,不是要存储的字面文本。点路径目标 "stock.available" 只更新该嵌套字段,保留 stock.rack 和其他全部原始字段。
updateMany 只作用于 repairable 匹配记录。已有有效 int/long 数量不匹配该仅字符串选择器,因此保留原类型。没有正确筛选时,转换可能在此前记录已改变后,因某个不可转换值而停止;整个多记录更新不是原子的。使用 onError: 0 或 onNull: 0 会编造数量,违反任务。此预备顺序场景没有并发写入方。
与上一单元相同,REPAIR here-document 按字面写入完整文件:
cat > repair.js <<'REPAIR'
printjson(db.equipment.updateMany(
repairable,
[{$set: {"stock.available": {$toInt: "$stock.available"}}}]
));
REPAIR
先执行策略,使选择器名称在作用域内可用,再执行保存更新:
./catalog run policy.js repair.js
查找 matchedCount: 2 和 modifiedCount: 2。检查实际文档和类型,因为仅凭修改记录数不能证明满足保留要求:
./catalog show
./catalog types
KIT-103 现在为 Int32 12,KIT-104 为 Int32 零值。KIT-102 必须仍保留原始 long 零值。原始名称、货架、供应商字段和 ID 全部保留。检查剩余分类:
./catalog classify policy.js
四条活跃记录必须全部在 valid 中,另外两组为空。注意为何审查前必须隔离:仅转换不会移除 null、缺失或不确定值。
重放批准的转换:
./catalog run policy.js repair.js
两个计数现在都应为零,因为没有剩余批准字符串。这是幂等转换,并不表示每种可能的数据库错误都会自动回滚此前记录。文件有语法错误时,重写完整 here-document 并重跑。文件名错误时,用 ls 修正;保留现有数据库,不要重置。
强制校验后续写入并保留正常操作
本步骤中,你将对未来的原生 MongoDB 写入应用已接受文档契约,并证明店铺仍可创建及更新有效套件。从 Terminal 开始,工作目录为 /home/labex/project/catalog-desk。
MongoDB collMod 命令修改现有集合选项。这里将同一个 valid 选择器附加为校验器。validationLevel: "strict" 校验插入和更新,包括对原本无效记录的更新。validationAction: "error" 拒绝违规写入。moderate 可豁免对已有无效记录的更新;warn 可记录日志但允许违规写入。两者都不是此处要求的严格后续写入契约。
附加校验器不会追溯清理数据:即使已有无效记录仍存在,collMod 也能成功。因此你先隔离不确定原件、只转换批准字符串,并审查活跃商品目录。成功命令响应证明选项改变;真实接受或拒绝写入才证明其实际作用。
保存原生命令。db.runCommand 在当前课程数据库执行它,printjson 显示实际响应:
cat > enforce.js <<'ENFORCE'
printjson(db.runCommand({
collMod: "equipment",
validator: valid,
validationLevel: "strict",
validationAction: "error"
}));
ENFORCE
原样运行策略和新文件:
./catalog run policy.js enforce.js
预期 ok: 1。读取真实集合选项:
./catalog status
输出应包含 equipment 校验器,以及 validationLevel: "strict" 和 validationAction: "error"。此读取工具还报告真实服务器和 shell 版本、所选数据库,不会替你生成校验成功结果。
用普通写入连接尝试一条不确定的未来插入。invalid-text 提交数量为 "12 kits" 的真实套件。**预期非零退出并显示 Document failed validation**,而非连接错误:
./catalog invalid-text KIT-902
确认没有保留部分新记录:
./catalog show KIT-902
结果应为 []。被拒绝写入没有将未知文本变成零,也没有创建替代隔离记录。未来无效写入会被拒绝;隔离记录保存的是较早接手数据的证据。
现在创建合法新套件。new ID COUNT 提交具有 Int32 数量、货架和供应商字段的文档。使用约定新 ID KIT-901 和初始数量 4:
./catalog new KIT-901 4
查找 KIT-901 插入已获确认的结果。额外货架和供应商字段必须允许存在。use ID COUNT 执行真实条件更新:只有记录具有足够数量时才扣减。使用一个单位:
./catalog use KIT-901 1
预期 matchedCount: 1 和 modifiedCount: 1。读取实际结果:
./catalog show KIT-901
KIT-901 应保留 name、货架 NEW 和供应商 LOCAL,可用数量为 Int32 3。原来四条清理后记录及所有隔离原件必须不变。严格整数契约仍允许已知零值、包含在范围内的上界、已有 long 数量、无关字段及普通有效更新。
new 成功后不要重放:唯一 _id 会产生重复键错误。除非确实要再次扣减,否则不要重放 use。保存修复脚本使用幂等的仅字符串谓词;普通库存使用操作则有意每次改变业务状态。如果不小心再次扣减 KIT-901,本课程只允许将这条新套件恢复至要求的最终数量。用相同 here-document 语法保存小型原生更新,再检查结果。Int32(3) 明确构造值为 3 的 BSON 32 位整数:
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
此恢复只针对你的新套件,应让最终数量保持 3。它不能用于覆盖接手原件或隔离原件。可复用策略、隔离、修复和强制校验文件现在表达完整受控迁移,实际商品目录则展示正常有效工作仍可进行。
总结
你转换了批准的数量字符串,没有替换其他嵌套字段或改变已有效数字的类型。你审查了清理后的商品目录,用 strict/error 校验强制执行契约,观察真实无效写入拒绝,并完成正常有效插入和更新。保存脚本及保留原件支持受控、可重复维护流程;不代表整个商品目录原子迁移,也不保证并发写入时安全。



