news 2026/9/20 14:29:54

RxDB MongoDB RxStorage 实战:让 MongoDB 成为本地优先数据库的存储引擎

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RxDB MongoDB RxStorage 实战:让 MongoDB 成为本地优先数据库的存储引擎
  • 数据库
  • NoSQL
  • 嵌入式数据库
  • 实时数据库

【免费下载链接】rxdb

The local-first database that runs on every JS runtime and replicates with your existing backend - no vendor, no lock-in - https://rxdb.info/

项目地址:https://gitcode.com/gh_mirrors/rx/rxdb
点击查看免费下载

MongoDB RxStorage 是 RxDB 官方提供的一种 RxStorage 实现,它允许你使用 MongoDB 作为 RxDB 数据库的底层存储引擎,从而同时获得 MongoDB 的成熟生态与可扩展性,以及 RxDB 的实时同步能力。读完本文,你将掌握 MongoDB RxStorage 的安装接入方式、连接串配置、已知限制与源码级工作原理,并了解它如何与 MongoDB 复制插件配合构建完整的实时同步方案。

什么是 MongoDB RxStorage

RxDB 本身并不是一个自包含的数据库,它把数据真正存放的位置抽象为 RxStorage 接口。通过切换不同的 RxStorage 实现,RxDB 可以在浏览器、Node.js、React Native 等不同 JavaScript 运行时上使用完全不同的底层存储。MongoDB RxStorage 就是其中的一种服务端实现,它通过 MongoDB 官方的 Node.js 驱动(mongodb包)把 RxDB 的文档、索引、变更事件等全部落地到 MongoDB 中。

该存储被设计为可与任何形态的 MongoDB 配合工作:

  • 普通的 MongoDB Server(独立部署);
  • MongoDB Replica Set(副本集);
  • Sharded MongoDB Cluster(分片集群);
  • Atlas Cloud Database(云数据库)。

这意味着无论你的基础设施是自建机房还是云上托管,都可以把 MongoDB 作为 RxDB 的持久化层。需要说明的是,由于浏览器和移动端无法直接使用 MongoDB 的 wire protocol 连接副本集,MongoDB RxStorage 主要用于 Node.js 服务端场景。

当前版本的已知限制

在把 MongoDB RxStorage 引入生产环境之前,务必先了解它的三条边界(与 RxAttachment 等功能的取舍有关):

  1. 多 Node.js 服务器共享同一个 MongoDB 数据库目前不受支持。从源码看,实例的变更事件通过进程内的Subject广播(见 rx-storage-instance-mongodb.ts 中的changes$),跨进程的 MongoDB Change Stream 监听代码在源码中被注释掉并标注为可能的 premium 功能,因此多服务器场景下的变更传播无法保证。
  2. RxAttachments(附件)目前不受支持。存储实例的构造函数会对 schema 进行校验,一旦检测到schema.attachments存在就直接抛出错误'attachments not supported in mongodb storage, make a PR if you need that'getAttachmentData方法同样直接抛错。
  3. 不支持在 MongoDB 上做非 RxDB 的写入。RxDB 期望所有写入都经由自身完成并维护所需的元数据(如_rev_deleted_meta.lwt),外部直接写入会破坏 RxDatabase 的一致性,导致未定义行为。但你可以随时从外部对 MongoDB 存储执行只读查询,这不会影响 RxDB 的正常工作。

快速上手:把 RxDB 接入 MongoDB

使用 MongoDB RxStorage 只需两个步骤。

第一步:安装 mongodb 驱动包

npm install mongodb --save

mongodb是 MongoDB 官方的 Node.js 驱动。在本仓库中,它被声明为mongodb的依赖项(package.json 中为"mongodb": "^6.21.0 || ^7.0.0"),同时也是 RxDB 自身运行 MongoDB 相关测试和脚本时使用的驱动版本。

第二步:创建 RxDatabase 时启用 MongoDB RxStorage

import { createRxDatabase } from 'rxdb'; import { getRxStorageMongoDB } from 'rxdb/plugins/storage-mongodb'; const myRxDatabase = await createRxDatabase({ name: 'exampledb', storage: getRxStorageMongoDB({ /** * MongoDB connection string * @link https://www.mongodb.com/docs/manual/reference/connection-string/ */ connection: 'mongodb://localhost:27017,localhost:27018,localhost:27019' }) });

核心要点:

  • getRxStorageMongoDBrxdb/plugins/storage-mongodb子路径导入(该导出在 package.json 的./plugins/storage-mongodb映射中同时提供了requireimport两种格式);
  • connection参数接收标准的 MongoDB 连接字符串,示例中的多主机地址localhost:27017,27018,27019对应一个三节点副本集;
  • 返回的RxStorageMongoDB实例实现了 RxDB 的RxStorage接口,在 rx-storage-mongodb.ts 中可以看到它通过createStorageInstance创建真实的存储实例,并在创建前调用ensureRxStorageInstanceParamsAreCorrect校验参数。

connection之外的完整设置项定义在 mongodb-types.ts:

export type MongoDBDatabaseSettings = { connection: MongoDBConnectionString; // 例如 'mongodb://localhost:27017' transactionOptions?: TransactionOptions; // 可选,MongoDB 驱动的事务选项 };

源码级原理:MongoDB RxStorage 是如何工作的

理解底层实现有助于你在遇到问题时快速定位,也能帮助你评估它在生产环境中的行为。

文档存储与_id字段替换

MongoDB 使用_id作为默认主键,且其生成规则与 RxDB 的主键语义不同。为了不冲突,当 RxDB schema 的主键字段名为_id时,存储层会把它替换为内部字段__id(常量MONGO_ID_SUBSTITUTE_FIELDNAME,定义于 mongodb-helper.ts)。写入时swapRxDocToMongo_id改名为__id,读取时swapMongoToRxDoc再把它还原为_id,查询与排序条件也会做同样的转换(primarySwapMongoDBQuerySelectorswapToMongoSort)。

集合命名与索引创建

每个 RxDB 存储实例会连接到名为databaseName + '-v' + schema.version的数据库(例如exampledb-v0),集合名即为 collectionName。实例创建时会自动:

  1. createCollection创建集合;
  2. 把 schema 中的indexes数组展开,并为每个索引追加主键索引,然后调用createIndexes建立 MongoDB 索引(索引名由字段名以|连接而成,见getMongoDBIndexName)。

因此,你无需手工维护 MongoDB 侧索引,schema 定义即可驱动索引结构。

写入与冲突检测

由于 MongoDB 不支持跨文档事务(源码注释中明确说明),RxDB 采用"先比较前序版本再更新"的策略来保证一致性:

  • 插入:通过findOneAndUpdate配合$setOnInsertupsert: true实现"不存在才插入";若文档已存在则产生一个status: 409RxStorageWriteErrorConflict冲突错误;
  • 更新:通过findOneAndReplace,查询条件中同时带上_rev前序修订号,只有版本匹配才会替换成功;若失败则重新读取当前文档并返回冲突错误。

所有写操作通过writeQueue串行排队执行,避免并发写互相踩踏(详见 rx-storage-instance-mongodb.ts 的bulkWrite实现)。这与 RxDB 的修订号(revision)机制一脉相承,确保了在无事务支持的 MongoDB 上也能可靠地检出写冲突。

查询、计数与清理

  • 查询:RxDB 的 Mango 查询会被prepareMongoDBQuery转换为 MongoDB 的 selector 与 sort,再依次应用skiplimitsort,最终把结果逐条swapMongoToRxDoc还原为 RxDB 文档格式;
  • 计数:直接使用countDocuments,并返回mode: 'fast'
  • 清理cleanup通过deleteMany删除_deleted: true_meta.lwt早于now() - minimumDeletedTime的墓碑文档,这是 RxDB 清理机制(Cleanup)在 MongoDB 上的落地实现。

客户端连接管理

getMongoDBClient/closeMongoDBClient(见 mongodb-helper.ts)维护了一个按连接串为 key 的MONGO_CLIENT_CACHE,对同一个连接串复用MongoClient实例,并以引用计数管理生命周期:引用归零后延迟 2 秒再真正关闭连接,以便短期复用场景避免反复建连。连接时还会通过driverInfo把驱动标识标记为RxDB及对应版本,便于在 MongoDB 侧观察流量来源。

与 MongoDB 复制插件的关系

MongoDB RxStorage 解决的是"数据存在哪",而 MongoDB 复制插件解决的是"数据如何与其他服务同步"。两者可以独立使用,也可以组合:复制插件基于 MongoDB Change Stream 实现双向实时同步,其客户端通过 RxServer 的复制端点与 MongoDB 通信;而 MongoDB RxStorage 则适合在 Node.js 服务端把 MongoDB 直接作为 RxDB 的存储引擎。组合使用时,你可以让 RxDB 直接读写 MongoDB,再借助复制插件把变更分发到其他客户端或系统。

测试与本地运行

仓库内置了 MongoDB 相关的完整测试与运维脚本(见 package.json):

  • 启动本地 MongoDB 副本集(基于 Docker,mongo 8.0.4):
npm run mongodb:start

该命令启动三个端口(27017/27018/27019)并以--replSet rs0模式运行,与文档示例中的三主机连接串对应。停止命令为npm run mongodb:stop

  • 连接自检node ./config/mongodb-connection-tester.js(config/mongodb-connection-tester.js)会等待容器启动、初始化副本集并等待主节点就绪后执行一次插入,供 CI 判断数据库是否可用;
  • 运行测试
npm run test:node:mongodb # 以 mongodb 为默认存储运行 Node 端单元测试 npm run test:fast:mongodb # 快速模式测试(跳过 init 测试) npm run test:performance:mongodb

测试配置位于 test/unit/config.ts,其中 MongoDB 存储的测试连接串为mongodb://localhost:27017/?directConnection=true,并标注了该存储的测试能力矩阵:hasPersistence: truehasMultiInstance: falsehasAttachments: falsehasReplication: true——这与上文列出的限制完全一致,也是你评估功能覆盖范围的最直接依据。

生产使用建议

综合文档与源码,接入 MongoDB RxStorage 时有几点值得注意:

  1. 确保 MongoDB 可用性:写入依赖findOneAndReplace与 upsert 语义,请确保使用的 MongoDB 版本支持这些操作;副本集模式下建议在连接串中配置多个节点以提升容错。
  2. 外部只读、内部独占写:让所有写入都经由 RxDB 完成,外部系统如需读取数据可直接查询 MongoDB,但不要绕过 RxDB 直接修改文档,否则会破坏_rev与元数据的一致性。
  3. 避开不支持的子集:当前版本不要使用 attachments schema 字段,也不要部署多 Node.js 实例共享同一 MongoDB 数据库(这会绕开hasMultiInstance: false的边界)。
  4. 善用 schema 驱动索引:索引由 RxDB 在集合创建时自动建立,新增查询字段时先在 RxDB schema 的indexes中声明,以保证查询性能。

MongoDB RxStorage 让"本地优先 + 服务端 MongoDB"的架构成为可能:客户端获得 RxDB 的响应式查询与离线能力,服务端获得 MongoDB 的成熟存储与运维生态。结合上述限制与源码行为,你可以据此判断它是否适合你的项目场景。

  • 数据库
  • NoSQL
  • 嵌入式数据库
  • 实时数据库

【免费下载链接】rxdb

The local-first database that runs on every JS runtime and replicates with your existing backend - no vendor, no lock-in - https://rxdb.info/

项目地址:https://gitcode.com/gh_mirrors/rx/rxdb
点击查看免费下载

相关推荐

上一篇:开源项目推荐:Windows Imaging Tools
下一篇:vCheck-vSphere 终极指南:如何自动化监控VMware虚拟化环境

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 14:29:37

基于Python和Tkinter的电商用户购物行为可视化分析平台

简介:一份面向电商技术开发者、数据分析师与产品经理的 Python 实战项目文档,完整展示用户购物行为分析与可视化平台的搭建过程。文档系统讲解数据采集与清洗、K-means 用户分群、协同过滤个性化推荐、销售预测及 Matplotlib/Seaborn 可视化,…

作者头像 李华
网站建设 2026/9/20 14:29:04

MATLAB多输入多输出DNN全连接神经网络预测系统及GUI实战

简介:基于MATLAB的DNN全连接神经网络多输入多输出项目实例,适合具备一定编程基础、熟悉MATLAB和深度学习基础的技术爱好者及研发人员。项目系统讲述多维输入输出场景下的网络构建,涵盖环境准备、数据预处理、模型训练、防止过拟合、参数调整、…

作者头像 李华
网站建设 2026/9/20 14:27:20

VB6老系统接入OPC UA:基于COM互操作的稳定方案

简介:OPC UA客户端VB示例及配套工具包,面向工业自动化领域需要了解OPC UA通信机制的开发者与VB程序员,可用于快速搭建客户端原型、学习设备数据交换流程。压缩包共181个文件,包含VB源码工程(6个vb文件)、可…

作者头像 李华
网站建设 2026/9/20 14:27:13

ARINC 702A-6深度解析:飞行管理计算机系统的演进与工程实践

简介:ARINC 702A-6(2026)是AEEC发布的最新飞行管理计算机系统特性规范,面向航空电子系统设计、适航验证与机载软件研发人员,用于统一FMS的功能架构、接口协议、导航数据库和数据链通信要求。资源包内含1份PDF文档&…

作者头像 李华
网站建设 2026/9/20 14:26:53

轻量级CMS选型与实战:用Colibri搭建小型内容站的完整指南

接到一个内容站需求的时候,我第一反应是上WordPress。三十几个页面,一个团队博客,几个产品栏目,不上电商不上论坛,WordPress装上主题和插件之后,光后台更新就能让一台256MB的小机器吭哧半天。后来我把方案换…

作者头像 李华