Skip to content

fix(mongodb): 修复长整型筛选与 _id 更新失败#3296

Merged
t8y2 merged 3 commits into
t8y2:mainfrom
zipg:codex/fix-mongodb-long-id-2527
Jul 14, 2026
Merged

fix(mongodb): 修复长整型筛选与 _id 更新失败#3296
t8y2 merged 3 commits into
t8y2:mainfrom
zipg:codex/fix-mongodb-long-id-2527

Conversation

@zipg

@zipg zipg commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

背景

Issue #2527 在已发布修复后追加反馈:0.5.55 中,MongoDB 雪花 ID 仍存在三个相关问题:

  1. 表列表结构化筛选生成的 NumberLong(...) 查询无法执行;
  2. 筛选输入框手动输入 NumberLong(...) 同样无法执行;
  3. BSON Int64 类型的 _id 在查询结果中编辑保存时,被当作字符串条件,导致更新匹配不到文档。

原因

此前的修复会使用 Extended JSON $numberLong 保存长整型筛选精度,并在查询预览中显示为 NumberLong(...),但链路仍有缺口:

  • Mongo Shell 命令解析器只转换了 ObjectId 和日期构造器,没有识别 NumberLong,预览语句重新执行时会解析失败;
  • 原生 Rust MongoDB 驱动未将筛选中的 $numberLong 解码为 BSON Int64
  • 查询结果为避免 JavaScript 精度丢失,会把超长 Int64 显示为字符串,同时丢失 _id 的原始 BSON 类型,保存时最终生成了字符串匹配条件。

修改

  • Mongo Shell 命令解析器支持带引号和不带引号的 NumberLong(...),统一转换为 $numberLong
  • 原生 Rust 驱动在查询、写入和筛选路径中正确解析 Extended JSON Int64
  • 查询返回时为 BSON Int64 类型的 _id 保留类型元数据,表格仍显示纯数字;
  • 表列表和 SQL 查询结果保存/预览时使用原始类型化 _id,生成 NumberLong("...") 条件并精确更新;
  • Legacy MongoDB Agent 同步保留 Long _id 类型并按 Extended JSON ID 更新;
  • 编辑其他超出 JavaScript 安全整数范围的 Int64 值时,不再经过 Number 舍入。

实现保留了字符串 _id 的原有语义:即使数据库中同时存在数字文本相同的 String _id 和 Int64 _id,更新 Int64 文档也不会误改字符串文档。

验证

  • pnpm check:format、lint、typecheck、全量 2774 项测试通过;
  • cargo test -p dbx-core db::mongo_driver::tests --lib:45 项通过;
  • cargo fmt --all -- --check:通过;
  • ./gradlew :mongodb:test :mongodb:shadowJar:通过;
  • MongoDB 8.0.26 真实环境验证:
    • 原生 Rust 驱动使用 $numberLong 筛选命中 1 条;
    • Int64 _id 更新返回 1,回读值正确;
    • 同数字文本的 String _id 文档未被修改;
    • Legacy Java Agent 筛选命中 1 条,更新返回 modified_count: 1,回读值正确。

Refs #2527(修复该 Issue 的最新评论追加反馈)

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request changes: 长整型 _id 的整体处理方向没问题,但 Legacy MongoDB Agent 还有一个兼容性问题。

MongoAgent.parseId 现在会把所有以 { 开头的 _id 都交给 Document.parse。这会导致合法的 String _id(例如 "{}""{\"tenant\":1}")在更新和删除时被重新解释成 BSON Document,从而匹配错误的文档或完全匹配不到。

这里只应解析明确支持的标量 Extended JSON ID wrapper,例如单字段的 {"$numberLong":"..."};其他 JSON-looking 值仍应按原始字符串处理。请补充上述 String _id 的回归测试。

另外当前分支与 main 存在冲突;rebase 时需要保留 main 上最近加入的 JSON-looking string value 类型保护。

@zipg
zipg force-pushed the codex/fix-mongodb-long-id-2527 branch from 1977344 to a925f62 Compare July 13, 2026 15:11
@zipg

zipg commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

已按评审意见处理,并已 rebase 到最新 main:

  • Legacy MongoDB Agent 的 parseId 现在只解析“仅包含一个字符串型 $numberLong 字段”的 Extended JSON wrapper
  • {}{"tenant":1}、带额外字段的 wrapper 以及非法 $numberLong 均保留为原始 String _id
  • 解决冲突时同时保留了 main 新增的 JSON-looking string value 类型保护,以及本 PR 对原始 BSON _id 的序列化处理
  • 新增对应回归测试

验证通过:

  • :common:test :mongodb:test :mongodb:shadowJar
  • pnpm check(format、lint、typecheck、test)
  • Mongo 前端定向测试 58 项
  • Rust Mongo 驱动测试 45 项

修复提交:a925f626

@zipg
zipg requested a review from t8y2 July 13, 2026 16:29
@t8y2
t8y2 merged commit 2a5e7ac into t8y2:main Jul 14, 2026
7 checks passed
@t8y2

t8y2 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Thanks for the contribution! Merged in 2a5e7ac, will be released in the next version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants