Compass 导出报 Path collision:父对象与子字段不能重复投影
Compass 导出 CSV 报 Path collision 时,先查父对象和子字段是否重复投影。按输出要求整理字段,核对记录范围与类型,不修改集合来试错。
MongoDB Compass 可以浏览和查询集合,导出 CSV 时却报 Path collision at Contact.Email remaining portion Email。应先核对导出字段选择与查询投影中是否同时包含 Contact 和 Contact.Email;父对象与它内部的路径不能在同一个投影里重复指定。
这类冲突涉及返回字段的定义,不表示集合已经损坏。字段大小写要与实际文档一致,Contact 和 contact 不能随意互换。旧 Compass 版本的字段选择界面可能不同,下面按最终选择和投影判断,不承诺所有版本都有相同按钮。
没在当前文档看到字段,不等于集合里没有它
一个集合中的文档不一定都包含相同字段。当前浏览的文档没有 Email,不能证明其他文档也没有它;导出字段推断和实际导出范围还可能覆盖更多数据。
核对集合、过滤条件、Project 字段、聚合管道以及导出时选择的字段。错误指出 Contact.Email 时,查看是否既选了整个 Contact,又保留了它的一个或多个子字段。删除一个报错子字段后错误转向另一个子字段,应继续整理整个父子选择关系,而不是逐条删除业务数据。
以下是会冲突的投影结构示例,不应作为导出配置使用:
{ $project: { Contact: 1, "Contact.Email": 1 } }
把两个字段的顺序交换也会冲突;关键是路径包含关系。如果实际投影没有重叠,应保留 Compass、服务器版本及不含敏感值的字段结构,继续核对界面生成的请求。仅凭同一句错误不能确定所有版本都是同一个软件缺陷。
按需要选择完整对象或子字段
需要整个 Contact 时,保留父对象,取消它下面重复的子字段选择。以下聚合片段只说明合法的字段关系:
{ $project: { _id: 0, Contact: 1 } }
只需要 Email 时,保留子字段,取消父对象:
{ $project: { _id: 0, "Contact.Email": 1 } }
_id: 0 是示例中的输出选择,不是消除 Contact 路径冲突的必需条件。实际导出需要身份字段时应保留。包含字段与排除字段也不能任意混写,_id 的特殊排除规则不能推广到其他字段。
这些片段用于聚合阶段;Compass 查询栏的 Project 使用的是投影对象本身,不应把含 $project 的整个阶段贴进去。修改后先检查预览字段,再按原来的导出范围操作,避免意外只导出了过滤后的少量记录。
如果必须在 CSV 中得到一个独立 Email 列,应先规划不与父对象重叠的输出结构。可以在聚合中用独立名字承载子字段;下面只是局部投影片段:
{ $project: { _id: 0, Email: "$Contact.Email" } }
这会改变输出列名和结构,不能默认与原来整份 Contact 对象等价。字段缺失、数组、null、嵌套对象和不同类型的值,都应按下游需要检查,不能认为取消勾选后所有 CSV 列仍原样保留。
别用导出成功替代数据完整性检查
先保留原查询与导出设置,在允许的样本范围检查文件,再导出业务需要的完整范围。CSV 可能丢失 BSON 类型信息;需要保留结构和类型时,应评估合适的 Extended JSON 格式。Compass 导出本身也不是数据库备份流程。
当前 Compass 默认会转义可能被表格软件解释为公式的字符串。不要为追求与屏幕显示相同而随意关闭这个保护;下游确实需要原始值时,应在受控流程中明确处理方式。
验收包括导出完成、字段结构符合约定、记录范围正确,以及含有和缺少 Contact 的文档都能被解释。界面不再报错,只证明这次导出请求没有遇到同一冲突,不能证明数据或类型没有损失。
回退只需恢复原查询和字段选择,并保留或按规则删除本次导出文件。上述投影不会修改集合;不要为恢复列结构去删除字段、重建集合或把 CSV 重新导入原库。


