戰(zhàn):讓 MongoDB 成為本地優(yōu)先數(shù)據(jù)庫的存儲(chǔ)引擎)
數(shù)據(jù)庫NoSQL嵌入式數(shù)據(jù)庫實(shí)時(shí)數(shù)據(jù)庫【免費(fèi)下載鏈接】rxdbThe local-first database that runs on every JS runtime and replicates with your existing backend - no vendor, no lock-in - https://rxdb.info/項(xiàng)目地址https://gitcode.com/gh_mirrors/rx/rxdb點(diǎn)擊查看免費(fèi)下載MongoDB RxStorage 是 RxDB 官方提供的一種 RxStorage 實(shí)現(xiàn)它允許你使用 MongoDB 作為 RxDB 數(shù)據(jù)庫的底層存儲(chǔ)引擎從而同時(shí)獲得 MongoDB 的成熟生態(tài)與可擴(kuò)展性以及 RxDB 的實(shí)時(shí)同步能力。讀完本文你將掌握 MongoDB RxStorage 的安裝接入方式、連接串配置、已知限制與源碼級(jí)工作原理并了解它如何與 MongoDB 復(fù)制插件配合構(gòu)建完整的實(shí)時(shí)同步方案。什么是 MongoDB RxStorageRxDB 本身并不是一個(gè)自包含的數(shù)據(jù)庫它把數(shù)據(jù)真正存放的位置抽象為 RxStorage 接口。通過切換不同的 RxStorage 實(shí)現(xiàn)RxDB 可以在瀏覽器、Node.js、React Native 等不同 JavaScript 運(yùn)行時(shí)上使用完全不同的底層存儲(chǔ)。MongoDB RxStorage 就是其中的一種服務(wù)端實(shí)現(xiàn)它通過 MongoDB 官方的 Node.js 驅(qū)動(dòng)mongodb包把 RxDB 的文檔、索引、變更事件等全部落地到 MongoDB 中。該存儲(chǔ)被設(shè)計(jì)為可與任何形態(tài)的 MongoDB 配合工作普通的 MongoDB Server獨(dú)立部署MongoDB Replica Set副本集Sharded MongoDB Cluster分片集群Atlas Cloud Database云數(shù)據(jù)庫。這意味著無論你的基礎(chǔ)設(shè)施是自建機(jī)房還是云上托管都可以把 MongoDB 作為 RxDB 的持久化層。需要說明的是由于瀏覽器和移動(dòng)端無法直接使用 MongoDB 的 wire protocol 連接副本集MongoDB RxStorage 主要用于 Node.js 服務(wù)端場景。當(dāng)前版本的已知限制在把 MongoDB RxStorage 引入生產(chǎn)環(huán)境之前務(wù)必先了解它的三條邊界與 RxAttachment 等功能的取舍有關(guān)多 Node.js 服務(wù)器共享同一個(gè) MongoDB 數(shù)據(jù)庫目前不受支持。從源碼看實(shí)例的變更事件通過進(jìn)程內(nèi)的Subject廣播見 rx-storage-instance-mongodb.ts 中的changes$跨進(jìn)程的 MongoDB Change Stream 監(jiān)聽代碼在源碼中被注釋掉并標(biāo)注為可能的 premium 功能因此多服務(wù)器場景下的變更傳播無法保證。RxAttachments附件目前不受支持。存儲(chǔ)實(shí)例的構(gòu)造函數(shù)會(huì)對(duì) schema 進(jìn)行校驗(yàn)一旦檢測到schema.attachments存在就直接拋出錯(cuò)誤attachments not supported in mongodb storage, make a PR if you need thatgetAttachmentData方法同樣直接拋錯(cuò)。不支持在 MongoDB 上做非 RxDB 的寫入。RxDB 期望所有寫入都經(jīng)由自身完成并維護(hù)所需的元數(shù)據(jù)如_rev、_deleted、_meta.lwt外部直接寫入會(huì)破壞 RxDatabase 的一致性導(dǎo)致未定義行為。但你可以隨時(shí)從外部對(duì) MongoDB 存儲(chǔ)執(zhí)行只讀查詢這不會(huì)影響 RxDB 的正常工作。快速上手把 RxDB 接入 MongoDB使用 MongoDB RxStorage 只需兩個(gè)步驟。第一步安裝 mongodb 驅(qū)動(dòng)包npm install mongodb --savemongodb是 MongoDB 官方的 Node.js 驅(qū)動(dòng)。在本倉庫中它被聲明為mongodb的依賴項(xiàng)package.json 中為mongodb: ^6.21.0 || ^7.0.0同時(shí)也是 RxDB 自身運(yùn)行 MongoDB 相關(guān)測試和腳本時(shí)使用的驅(qū)動(dòng)版本。第二步創(chuàng)建 RxDatabase 時(shí)啟用 MongoDB RxStorageimport { 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 }) });核心要點(diǎn)getRxStorageMongoDB從rxdb/plugins/storage-mongodb子路徑導(dǎo)入該導(dǎo)出在 package.json 的./plugins/storage-mongodb映射中同時(shí)提供了require、import兩種格式connection參數(shù)接收標(biāo)準(zhǔn)的 MongoDB 連接字符串示例中的多主機(jī)地址localhost:27017,27018,27019對(duì)應(yīng)一個(gè)三節(jié)點(diǎn)副本集返回的RxStorageMongoDB實(shí)例實(shí)現(xiàn)了 RxDB 的RxStorage接口在 rx-storage-mongodb.ts 中可以看到它通過createStorageInstance創(chuàng)建真實(shí)的存儲(chǔ)實(shí)例并在創(chuàng)建前調(diào)用ensureRxStorageInstanceParamsAreCorrect校驗(yàn)參數(shù)。connection之外的完整設(shè)置項(xiàng)定義在 mongodb-types.tsexport type MongoDBDatabaseSettings { connection: MongoDBConnectionString; // 例如 mongodb://localhost:27017 transactionOptions?: TransactionOptions; // 可選MongoDB 驅(qū)動(dòng)的事務(wù)選項(xiàng) };源碼級(jí)原理MongoDB RxStorage 是如何工作的理解底層實(shí)現(xiàn)有助于你在遇到問題時(shí)快速定位也能幫助你評(píng)估它在生產(chǎn)環(huán)境中的行為。文檔存儲(chǔ)與_id字段替換MongoDB 使用_id作為默認(rèn)主鍵且其生成規(guī)則與 RxDB 的主鍵語義不同。為了不沖突當(dāng) RxDB schema 的主鍵字段名為_id時(shí)存儲(chǔ)層會(huì)把它替換為內(nèi)部字段__id常量MONGO_ID_SUBSTITUTE_FIELDNAME定義于 mongodb-helper.ts。寫入時(shí)swapRxDocToMongo把_id改名為__id讀取時(shí)swapMongoToRxDoc再把它還原為_id查詢與排序條件也會(huì)做同樣的轉(zhuǎn)換primarySwapMongoDBQuerySelector、swapToMongoSort。集合命名與索引創(chuàng)建每個(gè) RxDB 存儲(chǔ)實(shí)例會(huì)連接到名為databaseName -v schema.version的數(shù)據(jù)庫例如exampledb-v0集合名即為 collectionName。實(shí)例創(chuàng)建時(shí)會(huì)自動(dòng)createCollection創(chuàng)建集合把 schema 中的indexes數(shù)組展開并為每個(gè)索引追加主鍵索引然后調(diào)用createIndexes建立 MongoDB 索引索引名由字段名以|連接而成見getMongoDBIndexName。因此你無需手工維護(hù) MongoDB 側(cè)索引schema 定義即可驅(qū)動(dòng)索引結(jié)構(gòu)。寫入與沖突檢測由于 MongoDB 不支持跨文檔事務(wù)源碼注釋中明確說明RxDB 采用先比較前序版本再更新的策略來保證一致性插入通過findOneAndUpdate配合$setOnInsert與upsert: true實(shí)現(xiàn)不存在才插入若文檔已存在則產(chǎn)生一個(gè)status: 409的RxStorageWriteErrorConflict沖突錯(cuò)誤更新通過findOneAndReplace查詢條件中同時(shí)帶上_rev前序修訂號(hào)只有版本匹配才會(huì)替換成功若失敗則重新讀取當(dāng)前文檔并返回沖突錯(cuò)誤。所有寫操作通過writeQueue串行排隊(duì)執(zhí)行避免并發(fā)寫互相踩踏詳見 rx-storage-instance-mongodb.ts 的bulkWrite實(shí)現(xiàn)。這與 RxDB 的修訂號(hào)revision機(jī)制一脈相承確保了在無事務(wù)支持的 MongoDB 上也能可靠地檢出寫沖突。查詢、計(jì)數(shù)與清理查詢RxDB 的 Mango 查詢會(huì)被prepareMongoDBQuery轉(zhuǎn)換為 MongoDB 的 selector 與 sort再依次應(yīng)用skip、limit、sort最終把結(jié)果逐條swapMongoToRxDoc還原為 RxDB 文檔格式計(jì)數(shù)直接使用countDocuments并返回mode: fast清理cleanup通過deleteMany刪除_deleted: true且_meta.lwt早于now() - minimumDeletedTime的墓碑文檔這是 RxDB 清理機(jī)制Cleanup在 MongoDB 上的落地實(shí)現(xiàn)。客戶端連接管理getMongoDBClient/closeMongoDBClient見 mongodb-helper.ts維護(hù)了一個(gè)按連接串為 key 的MONGO_CLIENT_CACHE對(duì)同一個(gè)連接串復(fù)用MongoClient實(shí)例并以引用計(jì)數(shù)管理生命周期引用歸零后延遲 2 秒再真正關(guān)閉連接以便短期復(fù)用場景避免反復(fù)建連。連接時(shí)還會(huì)通過driverInfo把驅(qū)動(dòng)標(biāo)識(shí)標(biāo)記為RxDB及對(duì)應(yīng)版本便于在 MongoDB 側(cè)觀察流量來源。與 MongoDB 復(fù)制插件的關(guān)系MongoDB RxStorage 解決的是數(shù)據(jù)存在哪而 MongoDB 復(fù)制插件解決的是數(shù)據(jù)如何與其他服務(wù)同步。兩者可以獨(dú)立使用也可以組合復(fù)制插件基于 MongoDB Change Stream 實(shí)現(xiàn)雙向?qū)崟r(shí)同步其客戶端通過 RxServer 的復(fù)制端點(diǎn)與 MongoDB 通信而 MongoDB RxStorage 則適合在 Node.js 服務(wù)端把 MongoDB 直接作為 RxDB 的存儲(chǔ)引擎。組合使用時(shí)你可以讓 RxDB 直接讀寫 MongoDB再借助復(fù)制插件把變更分發(fā)到其他客戶端或系統(tǒng)。測試與本地運(yùn)行倉庫內(nèi)置了 MongoDB 相關(guān)的完整測試與運(yùn)維腳本見 package.json啟動(dòng)本地 MongoDB 副本集基于 Dockermongo 8.0.4npm run mongodb:start該命令啟動(dòng)三個(gè)端口27017/27018/27019并以--replSet rs0模式運(yùn)行與文檔示例中的三主機(jī)連接串對(duì)應(yīng)。停止命令為npm run mongodb:stop。連接自檢node ./config/mongodb-connection-tester.jsconfig/mongodb-connection-tester.js會(huì)等待容器啟動(dòng)、初始化副本集并等待主節(jié)點(diǎn)就緒后執(zhí)行一次插入供 CI 判斷數(shù)據(jù)庫是否可用運(yùn)行測試npm run test:node:mongodb # 以 mongodb 為默認(rèn)存儲(chǔ)運(yùn)行 Node 端單元測試 npm run test:fast:mongodb # 快速模式測試跳過 init 測試 npm run test:performance:mongodb測試配置位于 test/unit/config.ts其中 MongoDB 存儲(chǔ)的測試連接串為mongodb://localhost:27017/?directConnectiontrue并標(biāo)注了該存儲(chǔ)的測試能力矩陣hasPersistence: true、hasMultiInstance: false、hasAttachments: false、hasReplication: true——這與上文列出的限制完全一致也是你評(píng)估功能覆蓋范圍的最直接依據(jù)。生產(chǎn)使用建議綜合文檔與源碼接入 MongoDB RxStorage 時(shí)有幾點(diǎn)值得注意確保 MongoDB 可用性寫入依賴findOneAndReplace與 upsert 語義請確保使用的 MongoDB 版本支持這些操作副本集模式下建議在連接串中配置多個(gè)節(jié)點(diǎn)以提升容錯(cuò)。外部只讀、內(nèi)部獨(dú)占寫讓所有寫入都經(jīng)由 RxDB 完成外部系統(tǒng)如需讀取數(shù)據(jù)可直接查詢 MongoDB但不要繞過 RxDB 直接修改文檔否則會(huì)破壞_rev與元數(shù)據(jù)的一致性。避開不支持的子集當(dāng)前版本不要使用 attachments schema 字段也不要部署多 Node.js 實(shí)例共享同一 MongoDB 數(shù)據(jù)庫這會(huì)繞開hasMultiInstance: false的邊界。善用 schema 驅(qū)動(dòng)索引索引由 RxDB 在集合創(chuàng)建時(shí)自動(dòng)建立新增查詢字段時(shí)先在 RxDB schema 的indexes中聲明以保證查詢性能。MongoDB RxStorage 讓本地優(yōu)先 服務(wù)端 MongoDB的架構(gòu)成為可能客戶端獲得 RxDB 的響應(yīng)式查詢與離線能力服務(wù)端獲得 MongoDB 的成熟存儲(chǔ)與運(yùn)維生態(tài)。結(jié)合上述限制與源碼行為你可以據(jù)此判斷它是否適合你的項(xiàng)目場景。贊分享數(shù)據(jù)庫NoSQL嵌入式數(shù)據(jù)庫實(shí)時(shí)數(shù)據(jù)庫【免費(fèi)下載鏈接】rxdbThe local-first database that runs on every JS runtime and replicates with your existing backend - no vendor, no lock-in - https://rxdb.info/項(xiàng)目地址https://gitcode.com/gh_mirrors/rx/rxdb點(diǎn)擊查看免費(fèi)下載相關(guān)推薦RxDB RxStorage 層詳解為每種運(yùn)行環(huán)境選擇與組合最佳存儲(chǔ)引擎RxDB RxStorage 層詳解為每種運(yùn)行環(huán)境選擇與組合最佳存儲(chǔ)引擎 RxStorage 是 RxDB 的存儲(chǔ)抽象層它把「數(shù)據(jù)庫內(nèi)核」與「底層存儲(chǔ)引擎」數(shù)據(jù)庫NoSQL嵌入式數(shù)據(jù)庫實(shí)時(shí)數(shù)據(jù)庫RxDB Expo Filesystem RxStorage 實(shí)戰(zhàn)指南讓 React Native 數(shù)據(jù)庫讀寫超越 SQLiteRxDB Expo Filesystem RxStorage 實(shí)戰(zhàn)指南讓 React Native 數(shù)據(jù)庫讀寫超越 SQLite 本文以 RxDB 官方文檔數(shù)據(jù)庫NoSQL嵌入式數(shù)據(jù)庫實(shí)時(shí)數(shù)據(jù)庫F3D如何用極簡工具實(shí)現(xiàn)專業(yè)級(jí)3D模型預(yù)覽的完整指南F3D如何用極簡工具實(shí)現(xiàn)專業(yè)級(jí)3D模型預(yù)覽的完整指南 你是否曾為復(fù)雜的3D軟件安裝包而煩惱是否在尋找一款能快速預(yù)覽各種格式3D模型的輕量級(jí)工具今天我將為你數(shù)據(jù)庫NoSQL嵌入式數(shù)據(jù)庫實(shí)時(shí)數(shù)據(jù)庫上一篇開源項(xiàng)目推薦Windows Imaging Tools下一篇vCheck-vSphere 終極指南如何自動(dòng)化監(jiān)控VMware虛擬化環(huán)境創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考