MongoDB之增删改查全套語法錦囊️【初學者福利】

王小王-123 2022-01-08 06:55:00 阅读数:955

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" }


示例二:

{
"_id" : ObjectId("5e746c62040a548ab32fff13"), //ObjectId對象
"name" : "Zhang San",// 字符串
"age" : 18,// 數字
"alive" : true, // 布爾值
"hobbies" : ["Anime","Comic","Game", 19], // 列錶(數組)
"body": {
"height" : 170,
"weight" : 65
}, // 內嵌文檔
"courses" : [
{ "coursename" : "nosql" },
{ "coursename" : "mysql" },
{ "coursename" : "python" },
{ "coursename" : "linux" },
{ "coursename" : "kettle" }
] // 內嵌文檔的列錶
}

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為你要操作的集合的名稱

db.collection.insert(
<document or array of documents>,
{multi: false}
)

insertOne() 方法
添加一條文檔記錄

db.collection.insertOne(
<document>{}
)

insertMany() 方法
添加多條文檔記錄 ([]方括號錶示數組)

db.collection.insertMany(
[ <document 1> {} , <document 2> {}, ... ] --jsonArray
)
// 添加一條文檔記錄{"lastname":"wang", "firstname":"xiaowang"}到集合mycollection
db.mycollection.insert({"lastname":"wang", "firstname":"xiaowang"});
db.mycollection.insertOne({"lastname":"wang", "firstname":"wang"});
// 添加一個文檔記錄對象mydoc到集合mycollection, 使用insert或insertOne方法
var mydoc = {"lastname":"wang", "firstname":"xiaowang"};
db.mycollection.insert(mydoc);
// 3.2版後新的方法:insertOne
db.mycollection.insertOne(mydoc);
// 添加多條記錄到集合mycollection,使用insert或insertMany方法
// 多條文檔記錄,用[]組合,用逗號分隔
db.mycollection.insert(
[
{"lastname":"wang", "firstname":"xiaowang", "role":"teacher",
"teacher_id":"123", "title":"講師", "courses":[{"coursename":"nosql"},
{"coursename":"mysql"}]},
{"lastname":"wang", "firstname":"xiaowang", "role":"student",
"student_id":"456", "grade":"2019", "class":"1", "score":100}
] )
;
// 添加一個文檔數組mydocs(多條文檔的數組)到集合mycollection,使用insert或insertMany方法
// 多條文檔記錄用[]組合到一個數組mydocs中。
// 注意 coursename處於兩個花括號中,屬於兩個內嵌的文檔,不算重複的鍵
var mydocs = [
{
"lastname" : "wang",
"firstname" : "xiaowanag",
"role" : "teacher",
"teacher_id" : "2019814",
"title" : "講師",
"courses" : [
{ "coursename" : "nosql" },
{ "coursename" : "mysql" },
{ "coursename" : "python" },
{ "coursename" : "linux" },
{ "coursename" : "kettle" }
]
},
{
"lastname" : "xiaowang1",
"firstname" : "wang",
"role" : "student",
"student_id" : "2019000001",
"grade" : "2019",
"class" : "1",
"score" : 80
},
{
"lastname" : "w",
"firstname" : "Er",
"role" : "student",
"student_id" : "2019000002",
"grade" : "2019",
"class" : "1",
"score" : 70
}
];
db.mycollection.insert(mydocs);
// 3.2版後新的方法:insertMany
db.mycollection.insertMany(mydocs);

注意我們的insert方法和insertMany方法,具有一樣的效果

3.2 查詢文檔記錄

find() 方法
這裏給出了幾種常見的查詢方法,一般利用查詢操作符進行查詢

db.mycollection.find({"score":{$gt:70}},{student_id:1});
// 查詢集合mycollection中的文檔
db.mycollection.find();
// 將查詢結果"漂亮化"
db.mycollection.find().pretty();
// 查詢集合mycollection中鍵為role, 值為student的文檔記錄
db.mycollection.find( {"role" : "student"} );
// 將查詢條件寫入文檔對象ceriteria查詢
var criteria = { "role" : "student" };
db.mycollection.find(criteria);
// 使用內嵌對象的字段值查詢
db.mycollection.find({"courses.coursename":"mysql"})
操作 操作符 範例 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
// 按數據類型查詢
// 數值(double):1
// 字符串(string):2
// 對象(object):3
// 數組(array):4
// 二進制數據(binary):5
// 未定義(Undefined):6
// 對象ID(ObjectId): 7
// 布爾值(boolean):8
// 日期(date):9
// 空(null):10
db.mycollection.find({"score":{$type:1}});
// 查詢條件的邏輯運算 (AND)
db.mycollection.find({"role":"student","score":80});
// 查詢條件的邏輯運算 (OR) , 注意$or是一個數組[]
db.mycollection.find({$or:[{"role":"student"},{"role":"teacher"}]});
// 查詢條件的成員運算 (IN)
db.mycollection.find({"student_id":{$in:["2019000001","2019000002"]}})
等價於:
db.mycollection.find({$or:[{"student_id":"2019000001"},
{"student_id":"2019000002"}]})
// 限制查詢結果字段
// 查詢role是student的文檔中的score字段值(只返回_id和score)
// 類比 sql: select score from mycollection where role="student";
// projection格式: { field1: <value>, field2: <value> ... }
db.mycollection.find({role:"student"}, {score:1})
// 使用變量存放 查詢文檔 和 返回字段文檔(包含或者排除字段 1:包含 0:排除,不能混用(可以單獨排除_id))
my_query = {$or:[{"student_id":"2019000001"},{"student_id":"2019000002"}]}
my_projection = {"_id":0, "score": 1,"firstname":1, "lastname":1}
db.mycollection.find(my_query, my_projection)

範例集合

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 删除一個鍵值對
db.collection.updateOne|updateMany|replaceOne(
<query>,
<update>,
{
upsert: <boolean>,
collation: <document>
}
)

參數說明:
query : update的查詢條件,類似sql update查詢內where後面的。
update : update的對象和一些更新的操作符(如 inc...)等,也可以理解為sql update查詢內set後面的
upsert : 可選,這個參數的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認是false,不插入。
multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數為true,就把按條件查出來多條記錄全部更新。
writeConcern :可選,拋出异常的級別。

// 將學號(student_id)為2019000000的記錄的score的值更改為90
// 類比sql: update mycollection set score=90 where student_id='2019000000';
db.mycollection.update({"student_id":"2019000000"}, {$set:{"score":90}});
// 將所有的學生的的成績(score)增加5, 注意:修改多條記錄要使用{multi:true}
// 類比sql: update mycollection set score=score+5 where role='student';
db.mycollection.update({"role":"student"}, {$inc:{"score":5}}, {multi:true});
// 將所有的學生的成績提高5分
query1 = {"role":"student"}
update1 = {$inc:{"score":5}}
option1 = {}
db.mycollection.updateMany(query1, update1, option1)
// 將所有2018級的學生改為2019級
query2 = {"grade":"2018"}
update2 = {$set:{"grade":"2019"}}
option2 = {}
db.mycollection.updateMany(query2, update2, option2)
// 將學號為2019000003的學生的姓、名、班、級替換為指定的值
// 如果集合中沒有2019000003學生,則插入這個學生信息
query3 = {"student_id":"2019000003"}
update3 = {$set:{"score":60, "class":3, "grade":"2019", "firstname":"Yanzu",
"lastname":"Wu"}}
option3 = {"upsert":true}
db.mycollection.updateOne(query3, update3, option3)

注意這裏使用了,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() 方法
 

db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)

deleteOne() 方法
deleteMany() 方法

db.collection.deleteOne|deleteMany(
<query>,
{
writeConcern: <document>,
collation: <document>
}
)

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() 來回收磁盤空間。
 

db.repairDatabase()
// 或者
db.runCommand({ repairDatabase: 1 })
小結:
增: db.collection.insert(newdocs)
-> db.collection.insertOne|insertMany
删: db.collection.remove(querydoc)
-> db.collection.deleteOne|deleteMany
改: db.collection.update(querydoc, updatedoc or newdoc, {upset:true})
-> db.collection.updateOne|updateMany|replaceOne
查: db.collection.find(querydoc, projection)

var query = {"courses.course":"分布式數據庫原理與應用"}
var projection = {
_id:0,
major:1,
grade:1,
class:1,
courses:{$elemMatch:{"course":"分布式數據庫原理與應用"}}
}
db.students.find(query,projection)

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: 求最小值

// 按專業取所有學生的平均身高
db.getCollection("students").aggregate([
{$group:{_id:"$major", avgHeight:{$avg:"$height"}}}
])
// 按專業求女生平均身高低於170的專業平均身高,並排序
/*
SQL: select AVG(height) as avgHeight, major as _id
from students
where gender=0
group by major
having avgHeight>170
sorted by avgHeight DESC
*/
db.getCollection("students").aggregate([
//第一步,查數據
{$match:{gender:0}}
//第二步,限制返回字段
,{$project:{_id:0,major:1, grade:1, class:1, height:1}}
//第三步,分組求平均值
// _id: group by的字段, 字段名要加$符號前綴,錶示是一個字段名
// avgHeight: 新生成的平均值字段名
// $avg: 平均值操作符,它的值為要求平均值的字段名,注意加$前綴
,{$group:{_id:"$major", avgHeight:{$avg:"$height"}}
//第四步,篩選聚合結果
,{$match:{avgHeight:{$lte:170}}}
//第五步,排序,按照avgHeight的值從大到小排序, -1: DESC, 1:ASC
,{$sort:{avgHeight:-1}}
])
/*******************************************************
*示例:按專業-年級-班級-性別 列出全校學生的平均昇高
- 使用多個字段進行分組
*******************************************************/
db.getCollection("students").aggregate([
//第一步,查數據,可以不要,那麼對整個集合的數據進行操作
//{$match:{gender:0}},
//第二步,限制返回字段,也可以不要,那麼返回所有的字段
//{$project:{_id:0,major:1, grade:1, class:1, height:1}}
//第三步,分組求平均值,可以以多個字段聯合作為分組鍵,當多個字段的值都相等才是一組
{$group:{_id:{專業:"$major", 年級:"$grade", 班級:"$class", 性別:"$gender"},
avgHeight:{$avg:"$height"}}}
//第四步,篩選聚合結果
// ,{$match:{avgHeight:{$lte:170}}}
//第五步,排序,按照avgHeight的值從大到小排序, -1: DESC, 1:ASC
,{$sort:{avgHeight:-1}}
])
/*******************************************************
*示例:按專業-年級-班級 分組計算全校分布式數據庫課程的平均分
- 使用變量定義查詢條件和返回字段
- 對數組字段中的值進行聚合操作
- 使用多個字段進行分組
- 使用多個字段進行排序
*******************************************************/
var 查詢條件 = {"courses.course":"分布式數據庫原理與應用"}
var 返回字段 = {_id:0, major:1, grade:1, class:1, courses:1}
db.students.aggregate( [
// 第一步,查詢上分布式課程的學生,注意,這裏每個學生可能還有別的課程
{$match:查詢條件}
// 第二步,指定返回的字段值,這裏使用了前面定義的變量
,{$project: 返回字段}
// 第三步,由於課程信息是在一個數組中,所以先將數組拆開,將數據拉平
,{$unwind:"$courses"}
// 第四步,對非分布式數據庫的課程信息進行過濾,只匹配分布式數據庫課程的分數
,{$match:查詢條件}
// 第五步,對分布式數據庫的課程分數進行平均值計算
,{$group: {_id:{"m":"$major","g":"$grade",c:"$class"}, avgScore:
{$avg:"$courses.score"} } }
// 第六步,排序,1: ASE(從小到大,正序), -1: DESC(從大到小,反序)
,{$sort:{"_id.m":1,"_id.g":1, "_id.c":1}}
] )

4.4 MongoDB MapReduce

1、基本語法
1)定義MapReduce操作
 

db.collection.mapReduce(
function() {emit(key,value);}, //map 函數
function(key,values[]) {return reduceFunction}, //reduce 函數
{
out: collection,
query: document,
sort: document,
limit: number
}
)

使用 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的用處不大)
 

// mapreduce
// mapper: 采集單元數據鍵值對
var mapper = function(){
// key:group by 的字段,分組標准
var key = this.major
// value: 要進行聚合計算的字段
var value = 1
emit(key, value);
// {
{grade:2018,gender:1}, 1}
} /
/ map -- conbine+shuffle -> reduce
// {
{grade:2018,gender:1}, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}
// reducer: 聚合數據, 產生一個單值數據
var reducer = function(key,values){
// key: {grade:2018,gender:1}
// values [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
var result = Array.sum(values)
return result
} /
/ options: 設置輸入輸出
var options = {out:"output", query:{}}
db.students.mapReduce(mapper, reducer, options)
db.output.find()
// 求全體學生的平均身高
// map方法將每一個集合中的文檔轉化成如 {"全體學生",171},{"全體學生",171}...的輸出
var mapper=function(){emit("全體學生",this.height)};
// MongoDB內部將進行聚合
// reduce方法得到如{"全體學生",[171,172,173,...]}的輸入,然後對
values[171,172,173,...]數組進行avg()平均值運算,得到一個value
var reducer=function(key,values){return Array.avg(values)};
// options中我們指定輸出的數據將存入AvgHeight集合
var options={out:"AvgHeight"};
// 使用定義好的mapper,reducer方法和options設置進行mapReduce運算
db.students.mapReduce(map,reduce,options);
// 查詢結果集合AvgHeight
db.AvgHeight.find();
// 分專業-年級-班級計算平均身高
// 定義一個mapper方法,從集合中的每一個文檔中提取key-value對
var mapper=function(){
// 構造key,key可以是一個字符串,如:"大數據2018-1"
key=this.major+this.grade+"-"+this.class
// 構造key,key可以是一個文檔對象,如:{專業:"大數據",年級:2018,班級:1}
// key = {專業:this.major,年級:this.grade,班級:this.class};
// 構造value,這裏要計算身高,所以將height字段值作為value
value=this.height;
/* 返回key-value對,如:
{"大數據2018-1":171},{"大數據2018-1":172}, ... ,
{"應數2018-1":170},{"應數2018-1":173},{"應數2018-1":171} ... ,
{"應數2018-2":170},{"應數2018-2":171},{"應數2018-2":172} ... ,
*/
emit(key, value);
}
/* MongoDB將按照key進行數據聚合,得到values數組
{"大數據2018-1":[171,172,...]},
{"應數2018-1":[170,173,171,...]},
{"應數2018-2":[170,171,172,...]},
...
*/
// 對於每個key的values數組進行reduce操作,這裏我們要用數組的avg方法對[171,172,...]進行平
均值計算
var reducer=function(key,values){
return Array.avg(values);
}
// options中我們指定輸出的數據將存入AvgHeight集合
var options={out:"AvgHeight"};
// 使用定義好的mapper,reducer方法和options設置進行mapReduce運算
db.students.mapReduce(mapper,reducer,options);
// 查詢結果集合AvgHeight, 可以對結果進行排序
db.AvgHeight.find().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。
 

# 導出students集合中全部的數據到JSON文件
mongoexport --host=localhost:27017 --db=cqust --collection=students --type=json
--out=".\export\students.json"
# 導出students集合中全部的數據到JSON文件(jsonArray格式)
mongoexport --host=localhost:27017 --db=cqust --collection=students --type=json
--out=".\export\students.json" --jsonArray
# 使用JSON文件導入數據到students_recover集合
mongoimport --host=localhost:27017 --db=cqust --collection=students_recover --
type json --file=".\export\students.json"
# 使用JSON文件導入數據到students_recover集合
# 使用upsert mode更新/插入數據
mongoimport --host=localhost:27017 --db=cqust --collection=students_recover --
type json --file=".\export\students.json" --mode=upsert
# 使用JSON文件導入數據到students_recover集合(jsonArray格式)
# 使用--drop先删除目標集合
mongoimport --host=localhost:27017 --db=cqust --collection=students_recover --
type json --file=".\export\students.json" --jsonArray --drop
# 導出students集合的指定字段數據到CSV文件
mongoexport --host=localhost:27017 --db=cqust --collection=students --type=csv -
-out=".\export\students.csv" -
fields="name,gender,height,phone,role,sno,major,grade,class,courses"
# 導出students集合的指定字段(使用字段文件,每個字段寫一行)數據到CSV文件
mongoexport --host=localhost:27017 --db=cqust --collection=students --type=csv -
-out=".\export\students.csv" --fieldFile="fields.txt"
# 導入CSV文件中的數據到students_recover集合(用--drop選項先删除目標集合)
# 使用--headerline選項從CSV文件頭行獲得字段名
mongoimport --host=localhost:27017 --db=cqust --collection=students_recover --
type csv --file=".\export\students.csv" --headerline --drop
# 導入CSV文件中的數據到students_recover集合(用drop選項先删除目標集合)
# 使用--columnsHaveTypes選項以指定的JSON數據類型導入
# 使用--fields選項指定導入字段(字段名.數據類型格式是配合--columnsHaveTypes使用的)
# 使用--parseGrace=skipRow跳過頭行(在數據類型轉換失敗時跳過)
mongoimport --host=localhost:27017 --db=cqust --collection=students_recover --
type csv --file=".\export\students.csv" --
fields="name.string(),gender.string(),height.double(),phone.string(),role.string
(),sno.double(),major.string(),grade.string(),class.string(),courses.auto()" --
parseGrace=skipRow --columnsHaveTypes --drop

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的基礎,至於我們的實際運用,如何去真正的增删改查,後面的文章我會給出比較詳細的案例的!

每文一語

喜歡毫無理由

版权声明:本文为[王小王-123]所创,转载请带上原文链接,感谢。 https://gsmany.com/2022/01/202201080654594854.html