先给结论:不要直接改校验规则,而要先判断这次格式变化是“同一批对象的表达升级”,还是“对象集合本身换了”。前者应保留旧规范并新增一条兼容分支,后者应冻结旧输入、建立新的对象清单。判断依据不是格式看起来像不像,而是旧对象还能不能从新格式里无损还原。
一个常见场景是:原本以纯文本行提交的站点清单,被换成了带字段名的结构化记录。运营者把输入规范同步改成只认新格式,结果查询结果明显变少。这里有两种解释。
第一种是解析口径变化。新格式里同一对象被拆成多个字段,旧规范按整行匹配,新规范按字段匹配,字段缺失或命名不一致的对象就被判为无效。对象其实还在,只是没被读出来。
第二种是对象集合变化。新格式来自另一份导出,时间点、来源范围、去重规则都不同,原本能匹配的对象确实不在里面。此时改规范只是让问题暴露,不是造成问题。
两种解释对应完全不同的动作:前者要补兼容分支,后者要重建对象基线。
可以按下面顺序取证,每一步都能排除一部分猜测。
需要提醒:命中数下降本身不能证明任何一种解释。字段改名、大小写归一化、去重阈值调整,都会造成同样的下降。只有把“对象是否还在”和“解析是否读到”分开验证,结论才站得住。
做法一:保留旧规范,新增兼容分支。成立条件是旧对象能被新格式无损还原,且新旧格式会长期并存。代价是校验逻辑变复杂,后续每加一种格式都要维护一条分支,误判风险随分支数上升。
做法二:冻结旧输入,以新格式重建对象清单。成立条件是对象集合确实换了来源或范围,旧清单已不代表当前要处理的对象。代价是历史可比性中断,之前基于旧清单做的判断不能直接沿用。
取舍的关键不是哪种更“先进”,而是这次变化是否改变了对象身份。身份没变,用做法一;身份变了,用做法二。混用会同时承担两边的代价。
假设旧输入是每行一个域名,新输入是 {"host": "...", "note": "..."} 这样的记录。若旧域名都能从 host 字段还原,且 note 只是附加信息,那么改法是:主标识仍取域名,新增对 host 的读取,旧纯文本行继续接受。这样旧对象不会因为格式升级被误判为无效。
反过来,如果新记录里的 host 已经是另一批采集结果,旧域名大部分不在其中,那么正确动作是另建一份清单,并明确标注两份清单的时间与来源,而不是把两批对象塞进同一套校验里比较。
确定方向后,先做一次小范围试跑:用同一批样本分别走旧规范和新规范,记录“能解析”和“能匹配”两个数量。若两者差距集中在少数字段,按字段补兼容;若差距分布在主标识上,转为重建清单。
这个试跑结果直接决定下一步:差距可归因于字段,就继续维护多分支;差距无法归因于字段,就停止在旧规范上打补丁,避免把解析问题误当成对象问题反复调整。规范改完后,把判断依据和样本来源一并留存,下次格式再变时可以复用同一套取证顺序。