MongoDB CRUD操作:快照查詢

MongoDB CRUD操作:快照查詢

文章目錄

  • MongoDB CRUD操作:快照查詢
    • 對比本地和快照的讀關注
    • 舉例
      • 從相同的時間點運行查詢
      • 從過去某個時刻讀取數據的一致狀態
    • 配置快照保留時間
      • 磁盤空間和歷史記錄

使用快照查詢可以讀取最近某個時間點的數據,而且從MongoDB 5.0開始,可以使用讀關注"snapshot"來查詢二級節點上的數據,這顯著提高了應用程序讀取的通用性和彈性,而且無需像以前那樣,先創建數據的靜態副本,將其轉移到一個單獨的系統中,然后手動隔離這些長期運行的查詢,以免干擾正常運行工作負載。相反,可以在從一致的數據狀態讀取數據的同時,針對實時事務數據庫執行長期運行查詢。

在輔助節點上使用讀關注"snapshot"不會影響應用程序的寫工作量,只有應用程序讀取才會從隔離到輔助節點的長期運行查詢中受益。

下面的情況建議使用快照查詢:

  • 執行多個相關查詢,并確保每個查詢從同一時間點讀取數據。
  • 確保從過去某個時間點的一致數據狀態讀取數據。

對比本地和快照的讀關注

當使用MongoDB默認的本地讀取關注執行長時間運行的查詢時,查詢結果可能包含與查詢同時發生的寫入數據,因此,查詢可能會返回意外或不一致的結果。

為了避免這種情況,可以創建一個會話并指定讀關注"snapshot",通過讀取關注"snapshot",MongoDB可以通過快照隔離運行查詢,這意味著查詢只讀取最近單個時間點出現的數據。

舉例

從相同的時間點運行查詢

讀關注"snapshot"允許在會話中運行多個相關查詢,并確保每個查詢從相同的時間點讀取數據。

例如,動物收容所有一個寵物數據庫,其中包含每種寵物的集合。寵物數據庫有catsdogs兩個集合,它們都包含一個adoptable字段,表示寵物是否可以領養。其中,cats集合中的文檔如下所示:

{"name": "Whiskers","color": "white","age": 10,"adoptable": true
}

如果要查詢所有集合中可供收養的寵物總數,為了提供一致的數據視圖,需要返回兩個集合同一時間點的數據。這時,就可以在會話中使用讀關注快照:

mongoc_client_session_t *cs = NULL;
mongoc_collection_t *cats_collection = NULL;
mongoc_collection_t *dogs_collection = NULL;
int64_t adoptable_pets_count = 0;
bson_error_t error;
mongoc_session_opt_t *session_opts;cats_collection = mongoc_client_get_collection (client, "pets", "cats");
dogs_collection = mongoc_client_get_collection (client, "pets", "dogs");/* 使用 pets.cats 和 pets.dogs 數據作為示例 */
if (!pet_setup (cats_collection, dogs_collection)) {goto cleanup;
}/* 啟動會話快照 */
session_opts = mongoc_session_opts_new ();
mongoc_session_opts_set_snapshot (session_opts, true);
cs = mongoc_client_start_session (client, session_opts, &error);
mongoc_session_opts_destroy (session_opts);
if (!cs) {MONGOC_ERROR ("Could not start session: %s", error.message);goto cleanup;
}/** 執行下面的聚合管道,將合計值累加到adoptable_pets_count。**  adoptablePetsCount = db.cats.aggregate(*      [ { "$match": { "adoptable": true } },*        { "$count": "adoptableCatsCount" } ], session=s*  ).next()["adoptableCatsCount"]**  adoptablePetsCount += db.dogs.aggregate(*      [ { "$match": { "adoptable": True} },*        { "$count": "adoptableDogsCount" } ], session=s*  ).next()["adoptableDogsCount"]** 注意,要實現這個操作必須要通過mongoc_collection_aggregate把客戶端會話傳遞給選項,即:** mongoc_client_session_append (cs, &opts, &error);* cursor = mongoc_collection_aggregate (*    collection, MONGOC_QUERY_NONE, pipeline, &opts, NULL);*/
accumulate_adoptable_count (cs, cats_collection, &adoptable_pets_count);
accumulate_adoptable_count (cs, dogs_collection, &adoptable_pets_count);printf ("there are %" PRId64 " adoptable pets\n", adoptable_pets_count);

在上面的一系列操作中:

  • 使用MongoClient()與MongoDB實例建立連接。
  • 切換到pets數據庫。
  • 建立會話,該命令指定了snapshot=True,因此會話使用讀關注快照。
  • pets數據庫中的每個集合執行下列操作:
    • 使用$match過濾adoptable字段為True的文件。
    • 使用$count返回已篩選文檔的計數。
    • 用數據庫中的計數遞增adoptablePetsCount變量。
  • 打印adoptablePetsCount變量。

會話中的所有查詢都會讀取同一時間點出現的數據,因此,最終計數反映的是一致的數據快照。

注意:如果會話持續時間超過WiredTiger歷史記錄保留期(默認為 300 秒),查詢就會出現快照過舊(SnapshotTooOld)錯誤。

從過去某個時刻讀取數據的一致狀態

讀關注快照可確保查詢能讀取最近某個時間點出現的數據。例如:一家在線鞋店有一個sales集合,其中包含該店售出的每一件商品的數據。其中,sales集合中的一個文檔如下所示:

{"shoeType": "boot","price": 30,"saleDate": ISODate("2022-02-02T06:01:17.171Z")
}

每天晚上都會運行一個查詢來查看當天售出了多少雙鞋。每日銷售查詢如下所示:

mongoc_client_session_t *cs = NULL;
mongoc_collection_t *sales_collection = NULL;
bson_error_t error;
mongoc_session_opt_t *session_opts;
bson_t *pipeline = NULL;
bson_t opts = BSON_INITIALIZER;
mongoc_cursor_t *cursor = NULL;
const bson_t *doc = NULL;
bool ok = true;
bson_iter_t iter;
int64_t total_sales = 0;sales_collection = mongoc_client_get_collection (client, "retail", "sales");/* 使用'retail.sales'示例數據 */
if (!retail_setup (sales_collection)) {goto cleanup;
}/* 開始快照會話 */
session_opts = mongoc_session_opts_new ();
mongoc_session_opts_set_snapshot (session_opts, true);
cs = mongoc_client_start_session (client, session_opts, &error);
mongoc_session_opts_destroy (session_opts);
if (!cs) {MONGOC_ERROR ("Could not start session: %s", error.message);goto cleanup;
}if (!mongoc_client_session_append (cs, &opts, &error)) {MONGOC_ERROR ("could not apply session options: %s", error.message);goto cleanup;
}pipeline = BCON_NEW ("pipeline","[","{","$match","{","$expr","{","$gt","[","$saleDate","{","$dateSubtract","{","startDate","$$NOW","unit",BCON_UTF8 ("day"),"amount",BCON_INT64 (1),"}","}","]","}","}","}","{","$count",BCON_UTF8 ("totalDailySales"),"}","]");cursor = mongoc_collection_aggregate (sales_collection, MONGOC_QUERY_NONE, pipeline, &opts, NULL);
bson_destroy (&opts);ok = mongoc_cursor_next (cursor, &doc);if (mongoc_cursor_error (cursor, &error)) {MONGOC_ERROR ("could not get totalDailySales: %s", error.message);goto cleanup;
}if (!ok) {MONGOC_ERROR ("%s", "cursor has no results");goto cleanup;
}ok = bson_iter_init_find (&iter, doc, "totalDailySales");
if (ok) {total_sales = bson_iter_as_int64 (&iter);
} else {MONGOC_ERROR ("%s", "missing key: 'totalDailySales'");goto cleanup;
}

在上面的一系列操作中:

  • 使用$match$exprsaleDate字段進行過濾。
    • $expr允許在$match階段使用聚合表達式(如 NOW)。
  • 使用$gt運算符和$dateSubtract表達式,返回saleDate大于執行查詢前一天的文檔。
  • 使用 $count 返回匹配文檔的計數。計數存儲在 totalDailySales 變量中。
  • 指定讀關注快照,確保查詢從單一時間點讀取。

因為sales集合比較大,所以運行查詢可能需要幾分鐘時間。由于是在線商店,銷售可能在一天中的任何時間發生。

例如下面的情況:

  • 查詢在上午 12:00 開始執行。
  • 一位顧客在上午 12:02 時購買了三雙鞋。
  • 查詢在凌晨 12:04 執行完畢。

如果查詢不使用讀關注快照,那么在查詢開始和查詢結束之間發生的銷售額就會包含在查詢計數中,盡管這些銷售額并不是在報告當天發生的。這可能導致報告不準確,某些銷售額被計算兩次。

指定讀取 "快照 "后,查詢只返回查詢開始執行前不久數據庫中的數據。

如果查詢時間超過WiredTiger歷史保留期(默認情況下為 300 秒),查詢就會出錯,并顯示 SnapshotTooOld 錯誤。

配置快照保留時間

默認情況下,WiredTiger 存儲引擎會保留 300 秒的歷史記錄。使用 snapshot=true 的會話,從會話中的第一個操作開始到最后一個操作結束,總共可使用 300 秒。如果使用會話的時間更長,會話就會因 SnapshotTooOld 錯誤而失敗。同樣,如果使用讀關注快照來查詢數據,且查詢持續時間超過 300 秒,查詢就會失敗。

如果查詢或會話運行時間超過 300 秒,可以考慮延長快照保留時間,可以通過修改minSnapshotHistoryWindowInSeconds參數增加快照保留期,例如,把minSnapshotHistoryWindowInSeconds 的值設置為 600 秒:

db.adminCommand( { setParameter: 1, minSnapshotHistoryWindowInSeconds: 600 } )

磁盤空間和歷史記錄

需要注意,增加 minSnapshotHistoryWindowInSeconds 的值會增加磁盤使用量,因為服務器必須在指定的時間窗口內保持較早修改值的歷史記錄。磁盤空間的使用量取決于工作負載,工作量越大,需要的磁盤空間就越大。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/19088.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/19088.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/19088.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于51單片機的溫控風扇的設計–仿真設計

可實現通過DS18B20測量當前環境溫度 可實現通過溫度自動控制風扇轉速 可實現通過按鍵設置不同風速對應的溫度 可實現通過按鍵切換自動、手動模式 可實現在手動模式下通過按鍵調整風扇轉速 可實現通過LCD1602顯示溫度、風扇轉速擋位、自動/手動模式

【C++】模擬實現string類

🦄個人主頁:修修修也 🎏所屬專欄:C ??操作環境:Visual Studio 2022 目錄 一.了解項目功能 二.逐步實現項目功能模塊及其邏輯詳解 🎏構建成員變量 🎏實現string類默認成員函數 📌構造函數 📌析構函數…

k8s 全面掌控日志系統

概述 為了提高系統運維和故障排查的效率, 日志系統采用 ELK(Elasticsearch、Logstash、Kibana)技術棧,通過 FileBeats 作為日志收集器,將來自不同節點的日志數據匯總并存儲在 Elasticsearch 中,最終通過 K…

創建一個新的Spring Security應用程序,并使用JDBC連接數據庫

創建一個新的Spring Security應用程序,并使用JDBC連接數據庫 在這個教程中,我們將學習如何創建一個新的Spring Security應用程序,使用JDBC連接數據庫以獲取用戶信息并進行認證。我們還將學習如何配置Spring Security以從數據庫中獲取用戶和權…

Vue3使用Composition API實現響應式

title: Vue3使用Composition API實現響應式 date: 2024/5/29 下午8:10:24 updated: 2024/5/29 下午8:10:24 categories: 前端開發 tags: Vue3CompositionRefsReactiveWatchLifecycleDebugging 1. 介紹 Composition API是Vue.js 3中新增的一組API,用于在組件中組…

SQL 語言:嵌入式 SQL 和動態 SQL

文章目錄 基本概述嵌入式 SQL動態 SQL總結 基本概述 嵌入式SQL和動態SQL是兩種在應用程序中嵌入和使用SQL語句的方法。它們都允許開發人員在編程語言中編寫SQL語句,以便在應用程序中執行數據庫操作。然而,這兩種方法在實現方式、性能和靈活性方面存在一…

Java數據結構與算法(紅黑樹)

前言 紅黑樹是一種自平衡二叉搜索樹,確保在插入和刪除操作后,樹的高度保持平衡,從而保證基本操作(插入、刪除、查找)的時間復雜度為O(log n)。 實現原理 紅黑樹具有以下性質: 每個節點要么是紅色&#…

go語言學習之旅之Go結構體

在Go語言中,結構體(struct)是一種用戶定義的數據類型,用于組合不同類型的數據項。結構體可以包含其他結構體或基本數據類型的字段。以下是關于Go語言結構體的基本知識: 定義結構體: package mainimport &…

Python 之微信指數小程序數據抓取

Fiddler安裝和設置 安裝 Fiddler 安裝包可以從這里獲取,如果失效了可以自己網上找一個安裝。 鏈接:https://pan.baidu.com/s/1N30BoDWm2_dBL8i8GRzK5g?pwd1znv 提取碼:1znv 然后就是點擊安裝就好了,沒什么好多說的。 啟用…

刷代碼隨想錄有感(83):貪心算法——最大子數組和

題干&#xff1a; 代碼&#xff1a; class Solution { public:int maxSubArray(vector<int>& nums) {int res INT_MIN;int count 0;for(int i 0; i < nums.size(); i){count nums[i];if(count > res) res count;if(count < 0)count 0;}return res;} …

【創作活動】探索 GPT-4o:下一代語言模型的技術革命

&#x1f604; 19年之后由于某些原因斷更了三年&#xff0c;23年重新揚帆起航&#xff0c;推出更多優質博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有堅忍不拔之志 &#x1f390; 個人CSND主頁——Mi…

HTTP報文

HTTP報文 報文流 HTTP報文是在HTTP引用程序之間發送的數據塊&#xff0c;這些數據塊以一種文本形式的元信息開頭&#xff0c;這些信息描述了報文的內容和含義&#xff0c;后面跟著可選的數據部分&#xff0c;這些報文在客戶端&#xff0c;服務器和代理之間流動。 報文流入源…

git更改本地項目關聯到新倉庫

刪除現在遠程關聯的倉庫 git remote rm origin鏈接新倉庫 git remote add origin url(需要關聯的新倉庫地址)代碼提交到遠程倉庫master分支 git push --set-upstream origin master本地分支更新同步至遠程倉庫 比如本地有dev分支 git push origin dev:dev

前端項目開發,3個HTTP請求工具

這一小節&#xff0c;我們介紹一下前端項目開發中&#xff0c;HTTP請求會用到的3個工具&#xff0c;分別是fetch、axios和js-tool-big-box中的jsonp請求。那么他們都有哪些小區別呢&#xff1f;我們一起來看一下。 目錄 1 fetch 2 axios 3 js-tool-big-box 的 jsonp 請求 …

拷貝構造、移動構造、拷貝賦值、移動賦值

最近在學習C的拷貝構造函數時發現一個問題&#xff1a;在函數中返回局部的類對象時&#xff0c;并沒有調用拷貝構造函數。針對這個問題&#xff0c;查閱了一些資料&#xff0c;這里記錄整理一下。 調用拷貝構造函數的三種情況&#xff1a; ① 用一個類去初始化另一個對象時&a…

【數據結構與算法 | 基礎篇 | 隊列篇】力扣102, 107

1. 力扣102 : 二叉樹的層序遍歷 (1). 題 給你二叉樹的根節點 root &#xff0c;返回其節點值的 層序遍歷 。 &#xff08;即逐層地&#xff0c;從左到右訪問所有節點&#xff09;。 示例 1&#xff1a; 輸入&#xff1a;root [3,9,20,null,null,15,7] 輸出&#xff1a;[[3]…

對于高速信號完整性,一塊聊聊啊(18)

本文摘錄一篇Allegro進行后仿真的完整流程,可能allegro版本有點老,但整個過程還是描述比較詳細的。 目錄 1、獲取IBIS模型 1.1模型下載 1.2檢查IBIS模型 1.3IBIS轉換為DML 1.4保存DML模型 2、仿真準備 2.1疊層設置 2.2電源網格設置 2.3仿真庫配置 3、仿真 3.1拓撲…

刷爆leetcode第六期

題目一 用隊列實現棧 請你僅使用兩個隊列實現一個后入先出&#xff08;LIFO&#xff09;的棧&#xff0c;并支持普通棧的全部四種操作&#xff08;push、top、pop 和 empty&#xff09;。 實現 MyStack 類&#xff1a; void push(int x) 將元素 x 壓入棧頂。 int pop() 移除…

【漏洞復現】大華智能物聯綜合管理平臺 fastjson遠程代碼執行漏洞

0x01 產品簡介 大華ICC智能物聯綜合管理平臺對技術組件進行模塊化和松耦合&#xff0c;將解決方案分層分級&#xff0c;提高面向智慧物聯的數據接入與生態合作能力。 0x02 漏洞概述 由于大華智能物聯綜合管理平臺使用了存在漏洞的Fastson組件,未經身份驗讓的攻擊者可利用 /e…

M功能-支付平臺(六)

target&#xff1a;離開柬埔寨倒計時-217day 今天突然發現我在csdn居然把我ip屬地搞出來了&#xff0c;之前都沒注意到&#xff0c;哎 前言 M功能演示版本做到后期(也就是第二周的后面3天)真的很心酸&#xff0c;這邊安排的4后端后面都放棄了&#xff0c;覺得做不出來&#…