MongoDB之增删改查全套语法锦囊⭐️【初学者福利】
目錄
MongoDB概念
MongoDB Shell 基本命令
1.基本概念
3.數據庫(db)
3. 集合(collection)
3.1 添加文檔到集合
3.2 查詢文檔記錄
3.3 更新文檔記錄
3.4 刪除文檔記錄
4. 游標和腳本
4.5 單一功能聚合函數
4.6 導入與導出
4.7 備份與恢復
每文一語
MongoDB概念
點擊標題,即可跳轉到博主詳情文章,本文介紹了MongoDB的概念和基本的知識,至于MongoDB到底可以用來做什么,數據庫的存儲,而且是大數據的存儲,因為MongoDB是基于大數據分布式集群所建立的,廣泛的應用在數據量大的操作之上,我們可以把數據存儲在MongoDB集群上。
?
MongoDB Shell 基本命令
1.基本概念
| SQL術語/概念 | MongoDB術語/概念 | 解釋/說明 |
| database | db | 數據庫 |
| table | collection | 數據庫表/集合 |
| row | document | 數據記錄行/文檔 |
| column | field | 數據字段/域 |
| index | index | 索引 |
| table joins | 表連接,MongoDB不支持 | |
| primary key | primary key | 主鍵,MongoDB自動將_id字段設置為主鍵 |
文檔的基本結構:{ : , : {}, ... }
封閉符 {}
分隔符 ,
連接符 :
鍵的數據類型:UTF-8字符,可以用”“引起來,如”name“
的用戶命名規則:
(1)'_id' 為保留字段key
(2) 禁止使用'$'符號
(3) 禁止使用'.'符號
(4) 避免同一個{}中使用重復的
值的數據類型:MongoDB支持的任意數據類型
示例一:
{ "_id" : 1, "name" : "Zhang San" }
示例二:
MongoDB的基本數據類型
| 數據類型 | 描述 |
| String | 字符串。存儲數據常用的數據類型。在 MongoDB 中,UTF-8 編碼的字符串才是 合法的。 |
| Integer | 整型數值。用于存儲數值。根據你所采用的服務器,可分為 32 位或 64 位。 |
| Boolean | 布爾值。用于存儲布爾值(真/假)。 |
| Double | 雙精度浮點值。用于存儲浮點值。 |
| Min/Max keys | 將一個值與 BSON(二進制的 JSON)元素的最低值和最高值相對比。 |
| Arrays | 用于將數組或列表或多個值存儲為一個鍵。 |
| Timestamp | 時間戳。記錄文檔修改或添加的具體時間。 |
| Object | 用于內嵌文檔。 |
| Null | 用于創建空值。 |
| Symbol | 符號。該數據類型基本上等同于字符串類型,但不同的是,它一般用于采用特殊 符號類型的語言。 |
| Date | 日期時間。用 UNIX 時間格式來存儲當前日期或時間。你可以指定自己的日期時 間:創建 Date 對象,傳入年月日信息。 |
| Object ID | 對象 ID。用于創建文檔的 ID。 |
| Binary Data | 二進制數據。用于存儲二進制數據。 |
| Code | 代碼類型。用于在文檔中存儲 JavaScript 代碼。 |
| Regular expression | 正則表達式類型。用于存儲正則表達式。 |
3.數據庫(db)
// 查看當前服務器上的數據庫 show dbs; show databases; // 選擇名為mydb的數據庫(如果沒有則創建) use mydb; // 查看當前使用的數據庫 db; // 查看當前數據庫的統計信息 db.stats(); // 查看當前數據庫的操作信息 db.currentOp(); // 刪除當前數據庫 db.dropDatabase();3. 集合(collection)
?
// 查看當前數據庫中的集合
show collections;
show tables;
// 創建一個名為mycoll的集合
db.createCollection("mycoll");
// 重命名mycoll集合,新集合名叫mycollection
db.mycoll.renameCollection("mycollectioin")
// 清空一個名為mycollection的集合
db.mycollection.remove({});
// 刪除一個名問mycollection的集合
db.mycollection.drop();
3.1 添加文檔到集合
insert() 方法
注意:db.collection中,collection為你要操作的集合的名稱
insertOne() 方法
添加一條文檔記錄
insertMany() 方法
添加多條文檔記錄 ([]方括號表示數組)
注意我們的insert方法和insertMany方法,具有一樣的效果
3.2 查詢文檔記錄
find() 方法
這里給出了幾種常見的查詢方法,一般利用查詢操作符進行查詢
| 操作 | 操作符 | 范例 | SQL 語句的類似 |
| 等于 | : | db.mycollection.find({"role":"student"}) | whererole='student' |
| 小于 less than | $lt: | db.mycollection.find({"score":{$lt:80}}) | where score < 80 |
| 小于或等于less than /equal | $lte: | db.mycollection.find({"score": {$lte:80}}) | where score <=80 |
| 大于greater than | $gt: | db.mycollection.find({"score":{$gt:80}}) | where score > 80 |
| 大于或等于greater than /equal | $gte: | db.mycollection.find({"score": {$gte:80}}) | where score >=80 |
| 不等于 not equal | $ne: | db.mycollection.find({"score":{$ne:80}}) | where score !=80 |
范例集合
courses數組中包含一個分布式的課程(course), 而且(AND), courses數組中包含大于80的分數(score)
var 查詢條件1 = { "courses.course":"分布式數據庫原理與應用", "courses.score":{$gt:80} }; var 查詢條件2 = { "courses":{ $elemMatch:{ "course":"分布式數據庫原理與應用", "score":{$gt:90} } } }; // courses數組中包含一個 分布式課程而且其分數大于80 的數組元素 var 返回條件 = { _id:0, sno:1, // courses:1 courses:{$elemMatch:{"course":"分布式數據庫原理與應用"}} }; db.getCollection("students").find(查詢條件2, 返回條件)3.3 更新文檔記錄
update operators 更新操作符
| Name | Description |
| $currentDate | $currentDate:{'字段名':{$type:'date|timestamp'}} |
| $inc | increase : 字段值+1 |
| $min | 如果更新值更小才更新 |
| $max | 如果更新值更大才更新 |
| $mul | multiply: 字段值乘n |
| $rename | 重命名字段 |
| $set | 設置一個鍵值對 |
| $setOnInsert | 只在文檔不存在需要插入是設置的字段 |
| $unset | 刪除一個鍵值對 |
參數說明:
query : update的查詢條件,類似sql update查詢內where后面的。
update : update的對象和一些更新的操作符(如 inc...)等,也可以理解為sql update查詢內set后面的
upsert : 可選,這個參數的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認是false,不插入。
multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數為true,就把按條件查出來多條記錄全部更新。
writeConcern :可選,拋出異常的級別。
注意這里使用了,upset這個參數,這個參數在上面的參數介紹里面也有過說明,如果不存在這個那么就會執行插入操作
// 也可以使用replaceOne, 注意update3的寫法,不需要使用$set,... 操作符 query3 = {"student_id":"2019000004"} update3 = {"lastname":"Wu", "firstname":"Yanzu", "grade":"2019", "class":3, "score":60} option3 = {"upsert":true} db.mycollection.replaceOne(query3, update3, option3)update數組中的元素
// $push: 向數組的尾部添加一個元素,如果字段不存在則創建 // $push + $each : 批量push,將$each:[]中的元素依次push到數組中 // $pushAll = $push + $each 批量push // $addToSet:不重復的set集合 // $pop: 彈出數組的頭部元素或尾部元素: -1:頭部,1:尾部 // $pull: 刪除數組中的值 // 使用小標或者定位操作符$來操作數組 $表示querydoc中確定的數組元素 // 修改內嵌文檔數組中第n個元素的值 // 定位操作符$: 查詢條件一般是以數組中的元素為條件,使用$符號作為滿足查詢條件的第一條文檔對應的下標值?
?
3.4 刪除文檔記錄
remove() 方法
?
deleteOne() 方法
deleteMany() 方法
query :(可選)刪除的文檔的條件。
justOne : (可選)如果設為 true 或 1,則只刪除一個文檔,如果不設置該參數,或使用默認值
false,則刪除所有匹配條件的文檔。
writeConcern :(可選)拋出異常的級別。
范例大全
// 條件刪除學號為2019000002的文檔記錄 // 類比sql: delete from mycollection where student_id='2019000000'; db.mycollection.remove({"student_id":"2019000002"}); db.mycollection.deleteMany{"student_id":"2019000002"}); // 刪除第一條符合條件的文檔記錄 db.mycollection.remove({"role":"student"},justOne:true); // 或者 db.mycollection.deleteOne({"role":"student"});一般的,我們使用remove就可以很好的解決問題
// 刪除所有記錄 db.mycollection.remove({});remove() 方法 并不會真正釋放空間。需要繼續執行 db.repairDatabase() 來回收磁盤空間。
?
4. 游標和腳本
4.1 游標的用法
聲明一個游標
var mycursor = db.collection.find()hasNext() next()
var mycursor = db.collection.find() while(mycursor.hasNext()){ printjson(mycursor.next()); }forEach()
var getScore = function(doc) { for(i=0;i<doc.courses.length;i++) { if(doc.courses[i].course == "分布式數據庫原理與應用") { print(doc.name, doc.courses[i].score) }}} var query = {"courses.course":/^分布式/}; var proje = {"_id":0, name:1, courses:1}; var curNoSQL = db.students.find(query, proje); curNoSQL.forEach(getScore)4.2 腳本的執行
我們可以使用Navicat進行直接導入,這個一個軟件給我們提供的圖形界面,進行操作腳本
交互式命令load(script.js)
注意,windows路徑中包含\,在js中表示轉義符,必須使用 \\ 來表示\字符。
mongo命令
4.3 聚合管道 aggregate
$avg: 求平均值
$sum: 求和
$max: 求最大值
$min: 求最小值
4.4 MongoDB MapReduce
1、基本語法
1)定義MapReduce操作
?
使用 MapReduce 要實現兩個函數 Map 函數和 Reduce 函數,Map 函數調用 emit(key, value), 遍
歷 collection 中所有的記錄, 將key 與 value 傳遞給 Reduce 函數進行處理。
Map 函數必須調用 emit(key, value) 返回鍵值對。這個鍵可以是一個常量,也可以是原始文檔中
某個鍵的值
map :映射函數 (生成鍵值對序列,作為 reduce 函數參數)。
reduce 統計函數,reduce函數的任務就是將key-values變成key-value,也就是把values數
組變成一個單一的值value。
out 統計結果存放集合 (不指定則使用臨時集合,在客戶端斷開后自動刪除)。
query 一個篩選條件,只有滿足條件的文檔才會調用map函數。(query。limit,sort可以隨
意組合)
sort 和limit結合的sort排序參數(也是在發往map函數前給文檔排序),可以優化分組機制
limit 發往map函數的文檔數量的上限(要是沒有limit,單獨使用sort的用處不大)
?
4.5 單一功能聚合函數
// 查詢students集合中2019級的學生數量 db.students.count({"grade":2019}) // 查詢students集合中有哪些單獨的課程名 db.students.distinct("courses.course") //任務1:給全校分布式數據庫課程考試班級平均分前三名的班級中每個學生發獎 // (1)求分布式課程的班級平均分 // (2)排序取前三名的班級 // (3)更新前三名班級的學生文檔,增加一個prize字段var mapper = function() { for(var i=0;i<this.courses.length;i++) { if(this.courses[i].course=="分布式數據庫原理與應用") { var key = {課程:this.courses[i].course,專業:this.major,年 級:this.grade,班號:this.class}; var value = this.courses[i].score; emit(key,value);// {課程:"分布式數據庫原理與應用",班級:應用統計2018-2}, 79 }}} // {課程:"分布式數據庫原理與應用",班級:應用統計2018-2}, [79,87,67,99,......] var reducer = function(key, values){ return Array.avg(values) } // mapreduce結果數據輸出到nosql_avg_score集合 var options = {out:"nosql_avg_score"} // 執行mapreduce運算 db.students.mapReduce(mapper, reducer, options) // 查詢mapreduce得到的前三名的班級信息,將查詢結果放入一個游標 var cursor = db.nosql_avg_score.find().sort({"value":-1}).limit(3) // 定義一個變量n,記錄游標中的位置,由于游標next方法從第一個開始獲取,而且游標中的數據在前面已經做了sort排序,所以第一條數據就是第一名, 注意,在每一次while循環結束時,n會增加1 var n=1; while(cursor.hasNext()){ // 從游標中獲取一條數據 var doc = cursor.next(); // 查詢條件 var querydoc = {major:doc._id.專業, grade:doc._id.年級, class:doc._id.班號} // 更新條件,設置一個prize字段,值為“第幾名” var updatedoc = {$set:{prize:"第"+n+"名"}} // 執行數據更新 db.students.updateMany(querydoc, updatedoc) n++; // 循環題末尾,n自增1 } // 查詢students表驗證結果 db.students.find({prize:{$type:2}}) db.students.find() // 任務1升級版:給全校每門課程考試班級平均分前三名的班級中每個學生發獎 // (1)求各門課程的班級平均分 // (2)按課程,平均分排序 // (3)遍歷排序后的數據,對每門課程前三名的班級去更新對應的學生數據 // 數據的分片采集: key:{major,grade,class}, value:courses.$.score =>var mapper = function() { var cls = {major:this.major, grade:this.grade, class:this.class} for(var i=0;i<this.courses.length;i++) { cls.course = this.courses[i].course; var score = this.courses[i].score; //print(cls.major, cls.grade, cls.class, score); emit(cls, score); } } // 數據的聚合處理 var reducer = function(cls, scores) { return Array.avg(scores) } // 數據的輸入輸出 var options = {out:"avgScore"} db.avgScore.drop() db.students.mapReduce(mapper,reducer,options) // 將已經存在的獎prize刪除掉, 避免類型錯誤 db.students.updateMany({},{$unset:{"prize":1}}); // 得到按課程和平均分排序的班級列表 var cursor = db.avgScore.find().sort({"_id.course":1,"value":-1}) // 定義個變量n,表示第幾名,由于數據已經按照課程和分數排序,第一個獲取的分數就是第1名 var n = 1; // 定義2個變量,存放當前處理的數據的課程字段和上一次處理的課程字段 var curCourse, lstCourse; while(cursor.hasNext()) { var doc = cursor.next(); var query = {"major":doc._id.major, "grade":doc._id.grade,"class":doc._id.class}; // 將當前處理的課程字段賦值給curCoourse curCourse = doc._id.course; // 如果當前處理的字段和上一次處理的字段一樣 if(curCourse==lstCourse) { n+=1; // 只取前3名,當n小于等于3是,是前三名,更新學生prize數組 if(n<=3) { var prizename = curCourse+"第"+n+"名"; var updatedoc = {$push:{prize:prizename}}; db.students.updateMany(query,updatedoc); } else //只取前3名,所以n大于3的情況下,這個班級不處理,直接跳過 { lstCourse = curCourse; continue; } } else // 如果當前處理的課程curCourse和上一次處理的課程不一樣,要重置名詞變量n,重新取新 課程的前三名 { n=1; var prizename = curCourse+"第"+n+"名"; var updatedoc = {$push:{prize:prizename}}; db.students.updateMany(query,updatedoc); } // 處理一條數據后,將當前處理的課程賦值給lstCourse lstCourse = curCourse; } db.students.find({prize:{$type:2}}) // db.students.find()4.6 導入與導出
Navicat 轉儲js腳本 備份數據庫/集合
(1)右鍵點數據庫或者集合
(2)選擇“轉儲腳本文件” > “結構和數據”
Navicat 執行js腳本 還原數據庫/集合
(1) 右鍵點數據庫
(2) 選擇“運行腳本文件”
注意:文件編碼應根據js文件具體設置,默認UTF-8
Navicat 導出向導
Navicat 導入向導
mongoexport
關鍵參數說明:
-h,--host :代表遠程連接的數據庫地址,默認連接本地Mongo數據庫;
--port:????? 代表遠程連接的數據庫的端口,默認連接的遠程端口27017;
--uri:??????? 使用mongodb:// 連接uri, 如:"mongodb://localhost:27017/cqust"
-u,--username:代表連接遠程數據庫的賬號,如果設置數據庫的認證,需要指定用戶賬號;
-p,--password:代表連接數據庫的賬號對應的密碼;
-d,--db:?????????? 代表連接的數據庫;
-c,--collection:代表連接數據庫中的集合;
-f, --fields:????? 代表集合中的字段,可以根據設置選擇導出的字段;
--type:??????????? 代表導出輸出的文件類型,包括csv和json文件;
-o, --out:??????? 代表導出的文件名;
-q, --query:??? 代表查詢條件;
--skip:??????????? 跳過指定數量的數據;
--limit:??????????? 讀取指定數量的數據記錄;
--sort:??????????? 對數據進行排序,可以通過參數指定排序的字段,并使用 1 和 -1 來指定排序的方式,其中 1 為升序排列,而-1是用于降序排列,如sort({KEY:1})。
當查詢時同時使用sort,skip,limit,無論位置先后,最先執行順序 sort再skip再limit。
?
4.7 備份與恢復
# mongodump 備份數據庫cqust 到當前目錄下的dump目錄(默認) mongodump --host=localhost:27017 --db=cqust# mongorestore 從默認備份目錄dump恢復數據 # 不使用--drop:只恢復數據庫中沒有的數據 mongorestore --host=localhost:27017# 使用--drop:先刪除原有數據再完全 mongorestore --host=localhost:27017 --drop# mongodump 備份數據庫cqust的集合students 到cqustdump目錄(指定備份文件目錄) mongodump --host=localhost:27017 --db=cqust --collection=students -- out="D:\MongoDB\output\cqust_students_dump"# --nsInclude=cqust.students <=> --db=cqust --collection=students mongodump --host=localhost:27017 --nsInclude=cqust.students -- out="D:\MongoDB\output\cqust_students_dump"# mongorestore 從備份目錄中的BSON文件恢復集合students的數據(使用--drop先刪除集合再恢復) mongorestore --host=localhost:27017 --nsInclude=cqust.students -- dir="D:\MongoDB\output\cqustdump\cqust\students.bson" --drop mongorestore --host=localhost:27017 --db=cqust --collection=students -- dir="D:\MongoDB\output\cqustdump\cqust\students.bson.gz" --gzip --drop# mongodump 備份數據庫cqust的集合students 到一個存檔文件 mongodump --host=localhost:27017 --db=cqust --collection=students -- archive="D:\MongoDB\output\cqust-students.dump"# mongorestore 從存檔文件中恢復數據(使用--drop先刪除集合再恢復) mongorestore --host=localhost:27017 --archive="D:\MongoDB\output\cquststudents.dump" --drop# mongorestore 從存檔文件中恢復cqust數據庫students集合的數據到數據庫cqust的recover集合中 mongorestore --host=localhost:27017 --archive="D:\MongoDB\output\cquststudents.dump" --nsInclude=cqust.students --nsFrom=cqust.students -- nsTo=cqust.recover?
?
其實到了這一步,我們應該也就了解到了,我們的MongoDB的基本的操作語法,但是如果你是初學者,我建議你先看完上面的全部的語法案例和詳解,有利于學習和夯實MongoDB的基礎,至于我們的實際運用,如何去真正的增刪改查,后面的文章我會給出比較詳細的案例的!
每文一語
喜歡毫無理由
總結
以上是生活随笔為你收集整理的MongoDB之增删改查全套语法锦囊⭐️【初学者福利】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Verilog实现移位寄存器
- 下一篇: SRAM