最后更新時(shí)間:2017-07-13 11:10:49
原始文章鏈接:http://www.lovebxm.com/2017/07/13/mongodb_primer/
MongoDB - 簡介
官網(wǎng):https://www.mongodb.com/
MongoDB 是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫掉缺,由 C++ 語言編寫,旨在為 WEB 應(yīng)用提供可擴(kuò)展的高性能數(shù)據(jù)存儲(chǔ)解決方案戈擒。
MongoDB 是一個(gè)介于關(guān)系數(shù)據(jù)庫和非關(guān)系數(shù)據(jù)庫之間的產(chǎn)品眶明,是非關(guān)系數(shù)據(jù)庫當(dāng)中功能最豐富,最像關(guān)系數(shù)據(jù)庫的筐高。
MongoDB - 安裝及運(yùn)行
- 下載
07/05/2017 Current Stable Release (3.4.6)
https://www.mongodb.com/download-center#community
- 創(chuàng)建數(shù)據(jù)目錄
MongoDB 將數(shù)據(jù)目錄存儲(chǔ)在 db 目錄下搜囱,需手動(dòng)創(chuàng)建丑瞧。
E:\MongoDB\data\db
- 運(yùn)行 MongoDB 服務(wù)器
為了從命令提示符下運(yùn)行MongoDB服務(wù)器,你必須從MongoDB\bin
目錄中執(zhí)行mongod.exe
文件蜀肘,不要關(guān)閉服務(wù)绊汹。ctrl + c
關(guān)閉。
mongod.exe --dbpath E:\MongoDB\data\db
- MongoDB 后臺(tái)管理
運(yùn)行 mongo.exe
MongoDB Shell是MongoDB自帶的交互式Javascript shell,用來對MongoDB進(jìn)行操作和管理的交互式環(huán)境扮宠。
- 將 MongoDB 服務(wù)器作為 Windows 服務(wù)運(yùn)行
添加系統(tǒng)環(huán)境 path E:\MongoDB\Server\3.4\bin
檢測:cmd 中輸入 mongod --help
新建文件:E:\MongoDB\logs\logs.log
將 MongoDB 服務(wù)器作為 Windows 服務(wù)隨 Windows 啟動(dòng)而開啟:
mongod.exe --logpath "E:\MongoDB\logs\logs.log" --logappend --dbpath "E:\MongoDB\data" --directoryperdb --serviceName MongoDB --install
開啟 MongoDB 服務(wù):net start MongoDB
停止 MongoDB 服務(wù):net stop MongoDB
刪除 MongoDB 服務(wù):sc delete MongoDB
接下來就可以在 cmd 中運(yùn)行 E:\MongoDB\Server\3.4\bin
里面的 *.exe
程序了
- shell 控制臺(tái)
mongo
- 數(shù)據(jù)庫的還原
mongorestore
- 備份
mongodump
- mongodb 啟動(dòng)的參數(shù)
mongoDB - 主要特點(diǎn)
- MongoDB安裝簡單西乖。
- MongoDB的提供了一個(gè)面向文檔存儲(chǔ),沒有表結(jié)構(gòu)的概念坛增,每天記錄可以有完全不同的結(jié)構(gòu)获雕,操作起來比較簡單和容易。
- 完全的索引支持(單鍵索引收捣、數(shù)組索引典鸡、全文索引、地理位置索引 等)
- 你可以通過本地或者網(wǎng)絡(luò)創(chuàng)建數(shù)據(jù)鏡像坏晦,這使得MongoDB有更強(qiáng)的擴(kuò)展性萝玷。
- 如果負(fù)載的增加(需要更多的存儲(chǔ)空間和更強(qiáng)的處理能力) ,它可以分布在計(jì)算機(jī)網(wǎng)絡(luò)中的其他節(jié)點(diǎn)上這就是所謂的分片昆婿。
- Mongo支持豐富的查詢表達(dá)式球碉。查詢指令使用JSON形式的標(biāo)記,可輕易查詢文檔中內(nèi)嵌的對象及數(shù)組仓蛆。
- MongoDb 使用update()命令可以實(shí)現(xiàn)替換完成的文檔(數(shù)據(jù))或者一些指定的數(shù)據(jù)字段 睁冬。
- Mongodb中的Map/reduce主要是用來對數(shù)據(jù)進(jìn)行批量處理和聚合操作倒彰。
- Map和Reduce福铅。Map函數(shù)調(diào)用emit(key,value)遍歷集合中所有的記錄范咨,將key與value傳給Reduce函數(shù)進(jìn)行處理活逆。
- Map函數(shù)和Reduce函數(shù)是使用Javascript編寫的,并可以通過db.runCommand或mapreduce命令來執(zhí)行MapReduce操作砖瞧。
- GridFS是MongoDB中的一個(gè)內(nèi)置功能祷嘶,可以用于存放大量小文件宣蠕。
- MongoDB允許在服務(wù)端執(zhí)行腳本搁胆,可以用Javascript編寫某個(gè)函數(shù)弥搞,直接在服務(wù)端執(zhí)行,也可以把函數(shù)的定義存儲(chǔ)在服務(wù)端渠旁,下次直接調(diào)用即可攀例。
- MongoDB 支持多種編程語言:C C++ C# .NET Erlang Haskell Java JavaScript Lisp node.JS Perl PHP Python Ruby Scala 等
mongoDB - 工具
監(jiān)控
- Munin:網(wǎng)絡(luò)和系統(tǒng)監(jiān)控工具
- Gangila:網(wǎng)絡(luò)和系統(tǒng)監(jiān)控工具
- Cacti:用于查看CPU負(fù)載, 網(wǎng)絡(luò)帶寬利用率,它也提供了一個(gè)應(yīng)用于監(jiān)控 MongoDB 的插件顾腊。
GUI
- Robomongo(Robo 3T)
- Fang of Mongo – 網(wǎng)頁式粤铭,由Django和jQuery所構(gòu)成。
- Futon4Mongo – 一個(gè)CouchDB Futon web的mongodb山寨版杂靶。
- Mongo3 – Ruby寫成梆惯。
- MongoHub – 適用于OSX的應(yīng)用程序酱鸭。
- Opricot – 一個(gè)基于瀏覽器的MongoDB控制臺(tái), 由PHP撰寫而成。
- Database Master — Windows的mongodb管理工具
- RockMongo — 最好的PHP語言的MongoDB管理工具加袋,輕量級(jí), 支持多國語言.
mongoDB - 三大重要概念
1. database 數(shù)據(jù)庫
多個(gè)集合邏輯上組織在一起,就是數(shù)據(jù)庫抱既。
數(shù)據(jù)庫命名規(guī)范:
- 不能是空字符串("")职烧。
- 不得含有' '(空格)、.防泵、$蚀之、/、\和\0 (空字符)捷泞。
- 應(yīng)全部小寫足删。
- 最多64字節(jié)。
有一些數(shù)據(jù)庫名是保留的锁右,可以直接訪問這些有特殊作用的數(shù)據(jù)庫失受。
- admin: 從權(quán)限的角度來看,這是"root"數(shù)據(jù)庫咏瑟。要是將一個(gè)用戶添加到這個(gè)數(shù)據(jù)庫拂到,這個(gè)用戶自動(dòng)繼承所有數(shù)據(jù)庫的權(quán)限。一些特定的服務(wù)器端命令也只能從這個(gè)數(shù)據(jù)庫運(yùn)行码泞,比如列出所有的數(shù)據(jù)庫或者關(guān)閉服務(wù)器兄旬。
- local: 這個(gè)數(shù)據(jù)永遠(yuǎn)不會(huì)被復(fù)制,可以用來存儲(chǔ)限于本地單臺(tái)服務(wù)器的任意集合
- config: 當(dāng)Mongo用于分片設(shè)置時(shí)余寥,config數(shù)據(jù)庫在內(nèi)部使用领铐,用于保存分片的相關(guān)信息。
2. collection 集合
多個(gè)文檔組成一個(gè)集合宋舷,相當(dāng)于關(guān)系數(shù)據(jù)庫的表绪撵。
所有存儲(chǔ)在集合中的數(shù)據(jù)都是 BSON 格式,BSON 是類 JSON 的一種二進(jìn)制形式的存儲(chǔ)格式祝蝠,簡稱 Binary JSON莲兢。
集合名命名規(guī)范:
- 集合名不能是空字符串""。
- 集合名不能含有\(zhòng)0字符(空字符)续膳,這個(gè)字符表示集合名的結(jié)尾改艇。
- 集合名不能以"system."開頭,這是為系統(tǒng)集合保留的前綴坟岔。
- 用戶創(chuàng)建的集合名字不能含有保留字符谒兄。有些驅(qū)動(dòng)程序的確支持在集合名里面包含,這是因?yàn)槟承┫到y(tǒng)生成的集合中包含該字符社付。除非你要訪問這種系統(tǒng)創(chuàng)建的集合承疲,否則千萬不要在名字里出現(xiàn)$邻耕。
3. document 文檔
MongoDB 將數(shù)據(jù)存儲(chǔ)為一個(gè)文檔,數(shù)據(jù)結(jié)構(gòu)由鍵值對組成燕鸽。
MongoDB 文檔是一組鍵值對(即BSON兄世,二進(jìn)制的 JSON),類似于 JSON 對象啊研。字段值可以包含其他文檔御滩,數(shù)組及文檔數(shù)組。
文檔鍵命名規(guī)范:
- 鍵不能含有\(zhòng)0 (空字符)党远。這個(gè)字符用來表示鍵的結(jié)尾削解。
- .和$有特別的意義,只有在特定環(huán)境下才能使用沟娱。
- 以下劃線"_"開頭的鍵是保留的(不是嚴(yán)格要求的)氛驮。
需要注意的是:
- 文檔中的鍵值對是有序的。
- 文檔中的值不僅可以是在雙引號(hào)里面的字符串济似,還可以是其他幾種數(shù)據(jù)類型(甚至可以是整個(gè)嵌入的文檔)矫废。
- MongoDB區(qū)分類型和大小寫。
- MongoDB的文檔不能有重復(fù)的鍵砰蠢。
- 文檔的鍵是字符串磷脯。除了少數(shù)例外情況,鍵可以使用任意UTF-8字符娩脾。
MongoDB - 數(shù)據(jù)類型
ObjectId:主鍵赵誓,一種特殊而且非常重要的類型,每個(gè)文檔都會(huì)默認(rèn)配置這個(gè)屬性柿赊,屬性名為_id俩功,除非自己定義,方可覆蓋
MongoDB - 常見操作
查看當(dāng)前數(shù)據(jù)庫
db
查看所有數(shù)據(jù)庫
沒有數(shù)據(jù)的數(shù)據(jù)庫不予顯示
MongoDB 中默認(rèn)的數(shù)據(jù)庫為 test碰声,如果你沒有創(chuàng)建新的數(shù)據(jù)庫诡蜓,集合將存放在 test 數(shù)據(jù)庫中。
show dbs
連接到指定的數(shù)據(jù)庫
如果數(shù)據(jù)庫不存在胰挑,則創(chuàng)建數(shù)據(jù)庫蔓罚,否則切換到指定數(shù)據(jù)庫。
use db_name
查看服務(wù)器狀態(tài)
db.serverStatus()
查看數(shù)據(jù)庫統(tǒng)計(jì)信息
db.stats()
刪除數(shù)據(jù)庫
db.dropDatabase()
查看數(shù)據(jù)庫中所有集合
show tables
或
show collections
清空集合
刪除里面的文檔瞻颂,但集合還在
db.col_name.remove({})
刪除集合
db.col_name.drop()
查看集合詳細(xì)信息
MongoDB 的3.0后的版本分了三種模式 queryPlanner豺谈、executionStats、allPlansExecution
db.col_name.find({key:value}).explain("allPlansExecution")
MongoDB - 增刪改查
插入
MongoDB 使用 insert() 或 save() 方法向集合中插入文檔:
如果該集合不在該數(shù)據(jù)庫中贡这, MongoDB 會(huì)自動(dòng)創(chuàng)建該集合并插入文檔茬末。
insert() 或 save() 方法都可以向collection里插入數(shù)據(jù),兩者區(qū)別:
- 如果不指定 _id 字段,save() 方法類似于 insert() 方法丽惭。如果指定 _id 字段击奶,則會(huì)更新該 _id 的數(shù)據(jù)。
- 使用save函數(shù)责掏,如果原來的對象不存在柜砾,那他們都可以向collection里插入數(shù)據(jù),如果已經(jīng)存在换衬,save會(huì)調(diào)用update更新里面的記錄痰驱,而insert則會(huì)忽略操作
- insert可以一次性插入一個(gè)列表,而不用遍歷冗疮,效率高萄唇, save則需要遍歷列表檩帐,一個(gè)個(gè)插入术幔。
db.col_name.insert(document)
db.col_name.save(document)
插入一個(gè)文檔到 col 集合中:
db.col_1.insert({
title: 'MongoDB 教程',
description: 'MongoDB 是一個(gè) Nosql 數(shù)據(jù)庫',
by: '菜鳥教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
也可以將文檔數(shù)據(jù)定義為一個(gè)變量,如下所示:
document = ({
title: 'MongoDB 教程',
description: 'MongoDB 是一個(gè) Nosql 數(shù)據(jù)庫',
by: '菜鳥教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
});
db.col_2.insert(document)
刪除
remove() 函數(shù)是用來刪除集合中的數(shù)據(jù)
在執(zhí)行 remove() 函數(shù)前先執(zhí)行 find() 命令來判斷執(zhí)行的條件是否正確湃密,這是一個(gè)比較好的習(xí)慣诅挑。
db.col_name.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
- query :(可選)刪除的文檔的條件。
- justOne : (可選)如果設(shè)為 true 或 1泛源,則只刪除一個(gè)文檔拔妥。
- writeConcern :(可選)拋出異常的級(jí)別。
刪除集合中所有文檔
db.col.remove({})
移除 col_1 集合中 title 為 MongoDB save 的文檔达箍,只刪除第一條找到的記錄
db.col_1.remove({'title':'MongoDB save'}, 1)
更新
MongoDB 使用 update() 和 save() 方法來更新集合中的文檔
update() 方法用于更新已存在的文檔
db.col_name.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
- query : update 的查詢條件没龙,類似sql update查詢內(nèi)where后面的。
- update : update的對象和一些更新的操作符(如$,$inc...)等缎玫,也可以理解為sql update查詢內(nèi)set后面的
- upsert : 可選硬纤,這個(gè)參數(shù)的意思是,如果不存在 update 的記錄赃磨,是否插入記錄筝家,true 為插入,默認(rèn)是 false邻辉,不插入溪王。
- multi : 可選,mongodb 默認(rèn)是false,只更新找到的第一條記錄值骇,如果這個(gè)參數(shù)為true,就把按條件查出來多條記錄全部更新莹菱。
- writeConcern :可選,拋出異常的級(jí)別吱瘩。
通過 update() 方法來更新 col_1 集合中的 title
$set 操作符為部分更新操作符芒珠,只更新 $set 之后的數(shù)據(jù),而不是覆蓋之前的數(shù)據(jù)
db.col_1.update({ 'title': 'MongoDB 教程' }, { $set: { 'title': 'MongoDB' } })
以上語句只會(huì)修改第一條發(fā)現(xiàn)的文檔搅裙,如果要修改多條相同的文檔皱卓,則需要設(shè)置 multi 參數(shù)為 true裹芝。
db.col_1.update({ 'title': 'MongoDB 教程' }, { $set: { 'title': 'MongoDB' } }, { multi: true })
save() 方法通過傳入的文檔來替換已有文檔。語法格式如下:
db.col_name.save(
<document>,
{
writeConcern: <document>
}
)
以下實(shí)例中我們替換了 col_1 的文檔數(shù)據(jù):
document = ({
"_id": "1",
"title": "MongoDB save",
"description": "MongoDB 是一個(gè) Nosql 數(shù)據(jù)庫",
"by": "菜鳥",
"url": "http://www.runoob.com",
"tags": ["mongodb", "database", "NoSQL"],
});
db.col_1.save(document)
查詢
find() 方法娜汁,它返回集合中所有文檔嫂易。
findOne() 方法,它只返回一個(gè)文檔掐禁。
db.col_name.find(query, projection)
- query :可選怜械,使用查詢操作符指定查詢條件
- projection :可選,使用投影操作符指定返回的鍵傅事。查詢時(shí)返回文檔中所有鍵值缕允, 只需省略該參數(shù)即可(默認(rèn)省略)。
格式化輸出:
db.col_name.find().pretty()
查看集合中文檔的個(gè)數(shù):
db.col_name.find().count()
跳過指定數(shù)量的數(shù)據(jù):
db.col_name.find().skip()
讀取指定記錄的條數(shù):
db.col_name.find().limit()
排序:
sort()方法可以通過參數(shù)指定排序的字段蹭越,并使用 1 和 -1 來指定排序的方式障本,其中 1 為升序排列,而-1是用于降序排列响鹃。
db.col_name.find().sort({key:1})
sort()方法可以通過參數(shù)指定排序的字段驾霜,并使用 1 和 -1 來指定排序的方式,其中 1 為升序排列买置,而-1是用于降序排列粪糙。
Where 語句
如果你想獲取"col"集合中 "likes" 大于100,小于 200 的數(shù)據(jù)忿项,你可以使用以下命令:
db.col.find({likes : {$lt :200, $gt : 100}})
// 類似于SQL語句:
Select * from col where likes>100 AND likes<200;
條件操作符 | 中文 | 全英文 |
---|---|---|
$gt | 大于 | greater than |
$gte | 大于等于 | greater than equal |
$lt | 小于 | less than |
$lte | 小于等于 | less than equal |
$ne | 不等于 | not equal |
$type 操作符
用來檢索集合中匹配的數(shù)據(jù)類型
如果想獲取 "col" 集合中 title 為 String 的數(shù)據(jù)蓉冈,你可以使用以下命令:
db.col.find({"title" : {$type : 2}})
AND 條件
find() 方法可以傳入多個(gè)鍵(key),每個(gè)鍵(key)以逗號(hào)隔開轩触,語法格式如下:
db.col_name.find({key1:value1, key2:value2}).pretty()
// 類似于 SQL and 語句:
SELECT * FROM col_name WHERE key1='value1' AND key2=value2
OR 條件
db.col_name.find({ $or: [{ "by": "菜鳥教程" }, { "title": "MongoDB 教程" }] }).pretty()
// 類似于 SQL or 語句:
SELECT * FROM col_name WHERE key1=value1 OR key2=value2
AND 和 OR 聯(lián)合使用
db.col_name.find({
"likes": {
$gt: 50
},
$or: [{
"by": "菜鳥教程"
}, {
"title": "MongoDB 教程"
}]
}).pretty()
// 類似常規(guī) SQL 語句:
SELECT * FROM col_name where likes>50 AND (by = '菜鳥教程' OR title = 'MongoDB 教程')
MongoDB - 索引
注意:從 mongoDB 3.0 開始寞酿,ensureIndex 被廢棄,今后都僅僅是 createIndex 的一個(gè)別名怕膛。
索引通常能夠極大的==提高查詢的效率==熟嫩,如果沒有索引,MongoDB在讀取數(shù)據(jù)時(shí)必須掃描集合中的每個(gè)文件并選取那些符合查詢條件的記錄褐捻。
這種掃描全集合的查詢效率是非常低的掸茅,特別在處理大量的數(shù)據(jù)時(shí),查詢可以要花費(fèi)幾十秒甚至幾分鐘柠逞,這對網(wǎng)站的性能是非常致命的昧狮。
索引是特殊的數(shù)據(jù)結(jié)構(gòu),索引存儲(chǔ)在一個(gè)易于遍歷讀取的數(shù)據(jù)集合中板壮,索引是對數(shù)據(jù)庫表中一列或多列的值進(jìn)行排序的一種結(jié)構(gòu)
索引常用命令
getIndexes 查看集合索引情況
db.col_name.getIndexes()
hint 強(qiáng)制使用索引
db.col_name.find({age:{$lt:30}}).hint({name:1, age:1}).explain()
刪除索引(不會(huì)刪除 _id 索引)
db.col_name.dropIndexes()
db.col_name.dropIndex({firstname: 1})
createIndex() 方法
MongoDB使用 createIndex() 方法來創(chuàng)建索引
key 為你要?jiǎng)?chuàng)建的索引字段逗鸣,1為按升序創(chuàng)建索引,-1為按降序創(chuàng)建索引。
也可以設(shè)置使用多個(gè)字段創(chuàng)建索引(關(guān)系型數(shù)據(jù)庫中稱作復(fù)合索引)
db.col_name.createIndex({key:1})
createIndex() 接收可選參數(shù)撒璧,可選參數(shù)列表如下:
_id 索引
對于每個(gè)插入的數(shù)據(jù)透葛,都會(huì)自動(dòng)生成一條唯一的 _id 字段,_id 索引是絕大多數(shù)集合默認(rèn)建立的索引
> db.col_1.insert({x:10})
WriteResult({ "nInserted" : 1 })
> db.col_1.find()
{ "_id" : ObjectId("59658e56aaf42d1c98dd95a2"), "x" : 10 }
> db.col_1.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "runoob.col_1"
}
]
字段解釋:
v 表示 version卿樱,在 Mongo3.2 之前的版本中僚害,會(huì)存在 {v:0}(版本鎖為0)的情況。在3.2之后的版本中繁调,{v:0} 不再允許使用萨蚕,這部分可以不去關(guān)注,因?yàn)?v 由系統(tǒng)自動(dòng)管理
key 表示作為索引的鍵蹄胰。1 或 -1表示排序模式岳遥,1為升序,1為降序
name 表示索引的名字裕寨,默認(rèn)生成名稱的規(guī)則是作為
索引的字段_排序模式
ns 表示 namespace 命名空間浩蓉,由
數(shù)據(jù)庫名稱.集合名稱
組成
單鍵索引
最普通的索引,不會(huì)自動(dòng)創(chuàng)建
// 對 x 字段創(chuàng)建升序索引
> db.col_1.createIndex({x:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.col_1.find()
{ "_id" : ObjectId("59658e56aaf42d1c98dd95a2"), "x" : 10 }
> db.col_1.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "runoob.col_1"
},
{
"v" : 2,
"key" : {
"x" : 1
},
"name" : "x_1",
"ns" : "runoob.col_1"
}
]
多鍵索引
單鍵索引的值為一個(gè)單一的值帮坚,多鍵索引的值有多個(gè)數(shù)據(jù)(如數(shù)組)
如果mongoDB中插入數(shù)組類型的多鍵數(shù)據(jù)妻往,索引是自動(dòng)建立的互艾,無需刻意指定
> db.col_1.insert({z:[1,2,3,4,5]})
WriteResult({ "nInserted" : 1 })
> db.col_1.find()
{ "_id" : ObjectId("59658e56aaf42d1c98dd95a2"), "x" : 10 }
{ "_id" : ObjectId("5965923eaaf42d1c98dd95a3"), "y" : 20 }
{ "_id" : ObjectId("59659828aaf42d1c98dd95a4"), "z" : [ 1, 2, 3, 4, 5 ] }
> db.col_1.find({z:3})
{ "_id" : ObjectId("59659828aaf42d1c98dd95a4"), "z" : [ 1, 2, 3, 4, 5 ] }
復(fù)合索引
同時(shí)對多個(gè)字段創(chuàng)建索引
> db.col_2.insert({x:10,y:20,z:30})
WriteResult({ "nInserted" : 1 })
> db.col_2.find()
{ "_id" : ObjectId("59659a57aaf42d1c98dd95a5"), "x" : 10, "y" : 20, "z" : 30 }
> db.col_2.createIndex({x:1,y:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.col_2.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "runoob.col_2"
},
{
"v" : 2,
"key" : {
"x" : 1,
"y" : 1
},
"name" : "x_1_y_1",
"ns" : "runoob.col_2"
}
]
過期索引
又稱 TTL(Time To Live试和,生存時(shí)間)索引,即在一段時(shí)間后會(huì)過期的索引(如登錄信息纫普、日志等)
過期后的索引會(huì)連同文檔一起刪除
expireAfterSeconds:指定一個(gè)以秒為單位的數(shù)值阅悍,設(shè)定集合的生存時(shí)間。
注意:
- 存儲(chǔ)在過期索引字段的值必須是指定的時(shí)間類型(必須是 ISODate 或 ISODate 數(shù)組昨稼,不能使用時(shí)間戳节视,否則不能被自動(dòng)刪除)
- 如果指定了 ISODate 數(shù)組,則按照最小的時(shí)間進(jìn)行刪除
- 過期索引不能是復(fù)合索引(不能指定兩個(gè)過期時(shí)間)
- 刪除時(shí)間存在些許誤差(1 分鐘左右)
> db.col_3.insert({x:new Date()})
WriteResult({ "nInserted" : 1 })
> db.col_3.find()
{ "_id" : ObjectId("59659f3baaf42d1c98dd95a7"), "x" : ISODate("2017-07-12T04:02:03.835Z") }
> db.col_3.createIndex({x:1},{expireAfterSeconds:10})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.col_3.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "runoob.col_3"
},
{
"v" : 2,
"key" : {
"x" : 1
},
"name" : "x_1",
"ns" : "runoob.col_3",
"expireAfterSeconds" : 10
}
]
> db.col_3.find()
// 無返回
全文索引
場景:全網(wǎng)站關(guān)鍵詞搜索
key-value 中假栓,key 此時(shí)為 $**
(也可以是具體某 key)寻行,value 此時(shí)為一個(gè)固定的字符串(如 text
)
全文索引相似度,與 sort 函數(shù)一起使用效果更好
db.col_7.find({ $text: { $search: "aa bb" } }, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" } })
注意:
- 每個(gè)集合只能創(chuàng)建一個(gè)全文索引
- MongoDB 從 2.4 版本開始支持全文檢索匾荆,從 3.2 版本開始支持中文
- (好像)只能對整個(gè)單詞查詢拌蜘,不能對單詞的截取部分查詢
- 關(guān)鍵詞之間的空格表示
或
- 關(guān)鍵詞之前的 - 表示
非
- 關(guān)鍵詞加引號(hào)表示
與
(需用 \ 轉(zhuǎn)義)
> db.col_7.find()
{ "_id" : ObjectId("5965aa84aaf42d1c98dd95b0"), "title" : "aa bb cc", "author" : "白小明", "article" : "這是白小明的一篇文章,標(biāo)題《aa bb cc》" }
{ "_id" : ObjectId("5965aa8faaf42d1c98dd95b1"), "title" : "abc def", "author" : "白小明", "article" : "這是白小明的一篇文章牙丽,標(biāo)題《aa bb cc》" }
{ "_id" : ObjectId("5965aedfaaf42d1c98dd95b2"), "title" : "aa bb", "author" : "白小明", "article" : "這是白小明的一篇文章简卧,標(biāo)題《aa bb cc》" }
> db.col_7.createIndex({"title": "text"})
> db.col_7.find({$text:{$search:"aa"}})
{ "_id" : ObjectId("5965aa84aaf42d1c98dd95b0"), "title" : "aa bb cc", "author" : "白小明", "article" : "這是白小明的一篇文章,標(biāo)題《aa bb cc》" }
{ "_id" : ObjectId("5965aedfaaf42d1c98dd95b2"), "title" : "aa bb", "author" : "白小明", "article" : "這是白小明的一篇文章烤芦,標(biāo)題《aa bb cc》" }
> db.col_7.find({$text:{$search:"aa cc"}})
{ "_id" : ObjectId("5965aa84aaf42d1c98dd95b0"), "title" : "aa bb cc", "author" : "白小明", "article" : "這是白小明的一篇文章举娩,標(biāo)題《aa bb cc》" }
{ "_id" : ObjectId("5965aedfaaf42d1c98dd95b2"), "title" : "aa bb", "author" : "白小明", "article" : "這是白小明的一篇文章,標(biāo)題《aa bb cc》" }
> db.col_7.find({$text:{$search:"\"aa\" \"cc\""}})
{ "_id" : ObjectId("5965aa84aaf42d1c98dd95b0"), "title" : "aa bb cc", "author" : "白小明", "article" : "這是白小明的一篇文章,標(biāo)題《aa bb cc》" }
> db.col_7.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
{ "_id" : ObjectId("5965aedfaaf42d1c98dd95b2"), "title" : "aa bb", "author" : "白小明", "article" : "這是白小明的一篇文章铜涉,標(biāo)題《aa bb cc》", "score" : 1.5 }
{ "_id" : ObjectId("5965aa84aaf42d1c98dd95b0"), "title" : "aa bb cc", "author" : "白小明", "article" : "這是白小明的一篇文章智玻,標(biāo)題《aa bb cc》", "score" : 1.3333333333333333 }
> db.col_7.dropIndexes()
> db.col_7.createIndex({"author": "text"}))
> db.col_7.find({$text:{$search:"小明"}})})
>
> db.col_7.find({$text:{$search:"白小明"}})
{ "_id" : ObjectId("5965aa84aaf42d1c98dd95b0"), "title" : "aa bb cc", "author" : "白小明", "article" : "這是白小明的一篇文章,標(biāo)題《aa bb cc》" }
{ "_id" : ObjectId("5965aa8faaf42d1c98dd95b1"), "title" : "abc def", "author" : "白小明", "article" : "這是白小明的一篇文章芙代,標(biāo)題《aa bb cc》" }
{ "_id" : ObjectId("5965aedfaaf42d1c98dd95b2"), "title" : "aa bb", "author" : "白小明", "article" : "這是白小明的一篇文章尚困,標(biāo)題《aa bb cc》" }
地理位置索引
查看最近的點(diǎn)
MongoDB - 聚合
==分組計(jì)算==
MongoDB 中聚合主要用于處理數(shù)據(jù)(如平均值,求和等),并返回計(jì)算后的數(shù)據(jù)結(jié)果链蕊。類似sql語句中的 count(*)事甜。
aggregate() 方法
db.col_name.aggregate(AGGREGATE_OPERATION)
下表展示了一些聚合的表達(dá)式:
實(shí)例
計(jì)算每個(gè)作者所寫的文章數(shù)
在下面的例子中,我們通過字段by_user字段對數(shù)據(jù)進(jìn)行分組滔韵,并計(jì)算by_user字段相同值的總和逻谦。
集合中的數(shù)據(jù)如下:
{
"_id" : ObjectId("5963b992a812aa05b9d2e765"),
"title" : "MongoDB Overview",
"description" : "MongoDB is no sql database",
"by_user" : "runoob.com",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
{
"_id" : ObjectId("5963b9aaa812aa05b9d2e766"),
"title" : "NoSQL Overview",
"description" : "No sql database is very fast",
"by_user" : "runoob.com",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 10
}
{
"_id" : ObjectId("5963b9bba812aa05b9d2e767"),
"title" : "Neo4j Overview",
"description" : "Neo4j is no sql database",
"by_user" : "Neo4j",
"url" : "http://www.neo4j.com",
"tags" : [
"neo4j",
"database",
"NoSQL"
],
"likes" : 750
}
使用aggregate()計(jì)算結(jié)果如下:
db.col_1.aggregate([{
$group: {
_id: "$by_user",
num_tutorial: {
$sum: 1
}
}
}])
// 返回
{ "_id" : "Neo4j", "num_tutorial" : 1 }
{ "_id" : "runoob.com", "num_tutorial" : 2 }
// 以上實(shí)例類似sql語句
select by_user, count(*) from col_1 group by by_user
聚合管道
管道在Unix和Linux中一般用于將當(dāng)前命令的輸出結(jié)果作為下一個(gè)命令的參數(shù)。
MongoDB 的聚合管道將MongoDB文檔在一個(gè)管道處理完畢后將結(jié)果傳遞給下一個(gè)管道處理陪蜻。管道操作是可以重復(fù)的邦马。
表達(dá)式:處理輸入文檔并輸出。表達(dá)式是無狀態(tài)的宴卖,只能用于計(jì)算當(dāng)前聚合管道的文檔滋将,不能處理其它的文檔。
聚合管道常用的幾個(gè)操作:
- $project:修改輸入文檔的結(jié)構(gòu)症昏∷婷觯可以用來重命名、增加或刪除域肝谭,也可以用于創(chuàng)建計(jì)算結(jié)果以及嵌套文檔掘宪。
- $match:用于過濾數(shù)據(jù),只輸出符合條件的文檔攘烛。$match使用MongoDB的標(biāo)準(zhǔn)查詢操作魏滚。
- $limit:用來限制MongoDB聚合管道返回的文檔數(shù)。
- $skip:在聚合管道中跳過指定數(shù)量的文檔坟漱,并返回余下的文檔鼠次。
- $unwind:將文檔中的某一個(gè)數(shù)組類型字段拆分成多條,每條包含數(shù)組中的一個(gè)值芋齿。
- $group:將集合中的文檔分組腥寇,可用于統(tǒng)計(jì)結(jié)果。
- $sort:將輸入文檔排序后輸出沟突。
- $geoNear:輸出接近某一地理位置的有序文檔花颗。
實(shí)例
$project 實(shí)例
0 為不顯示,1為顯示惠拭,默認(rèn)情況下 _id 字段是 1
db.articles.aggregate({
$project: {
_id: 0,
title: 1,
by_user: 1,
}
});
// 返回
{ "title" : "MongoDB Overview", "by_user" : "runoob.com" }
{ "title" : "NoSQL Overview", "by_user" : "runoob.com" }
{ "title" : "Neo4j Overview", "by_user" : "Neo4j" }
$match 實(shí)例
$match 用于獲取分?jǐn)?shù)大于70小于或等于90記錄扩劝,然后將符合條件的記錄送到下一階段$group管道操作符進(jìn)行處理庸论。
db.articles.aggregate([
{ $match: { score: { $gt: 70, $lte: 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
]);
// 返回
{ "_id" : null, "count" : 1 }
$skip 實(shí)例
經(jīng)過 $skip 管道操作符處理后,前2個(gè)文檔被"過濾"掉棒呛。
db.col_1.aggregate({ $skip: 2 });
MongoDB - 復(fù)制
MongoDB 復(fù)制(副本集)是==將數(shù)據(jù)同步在多個(gè)服務(wù)器==的過程聂示。
復(fù)制提供了數(shù)據(jù)的冗余備份,并在多個(gè)服務(wù)器上存儲(chǔ)數(shù)據(jù)副本簇秒,提高了數(shù)據(jù)的可用性鱼喉, 并可以保證數(shù)據(jù)的安全性。
特點(diǎn):
保障數(shù)據(jù)的安全性
數(shù)據(jù)高可用性 (24*7)
災(zāi)難恢復(fù)趋观,復(fù)制允許您從硬件故障和服務(wù)中斷中恢復(fù)數(shù)據(jù)扛禽。
無需停機(jī)維護(hù)(如備份,重建索引皱坛,壓縮)
分布式讀取數(shù)據(jù)
N 個(gè)節(jié)點(diǎn)的集群
任何節(jié)點(diǎn)可作為主節(jié)點(diǎn)
所有寫入操作都在主節(jié)點(diǎn)上
自動(dòng)故障轉(zhuǎn)移
自動(dòng)恢復(fù)
復(fù)制原理
mongodb 的復(fù)制至少需要兩個(gè)節(jié)點(diǎn)编曼。
- 其中一個(gè)是==主節(jié)點(diǎn)==,負(fù)責(zé)處理客戶端請求剩辟,
- 其余的都是==從節(jié)點(diǎn)==掐场,負(fù)責(zé)復(fù)制主節(jié)點(diǎn)上的數(shù)據(jù)。
mongodb各個(gè)節(jié)點(diǎn)常見的搭配方式為:一主一從贩猎、一主多從熊户。
主節(jié)點(diǎn)記錄在其上的所有操作oplog,從節(jié)點(diǎn)定期輪詢主節(jié)點(diǎn)獲取這些操作吭服,然后對自己的數(shù)據(jù)副本執(zhí)行這些操作嚷堡,從而保證從節(jié)點(diǎn)的數(shù)據(jù)與主節(jié)點(diǎn)一致。
復(fù)制設(shè)置
- 關(guān)閉正在運(yùn)行的MongoDB服務(wù)器噪馏。
現(xiàn)在我們通過指定 --replSet 選項(xiàng)來啟動(dòng)mongoDB
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"
實(shí)例:
下面實(shí)例會(huì)啟動(dòng)一個(gè)名為rs0的MongoDB實(shí)例麦到,其端口號(hào)為27017绿饵。
啟動(dòng)后打開命令提示框并連接上mongoDB服務(wù)欠肾。
在Mongo客戶端使用命令rs.initiate()來啟動(dòng)一個(gè)新的副本集。
我們可以使用rs.conf()來查看副本集的配置
查看副本集狀態(tài)使用 rs.status() 命令
mongod --port 27017 --dbpath "D:\set up\mongodb\data" --replSet rs0
副本集添加成員
添加副本集的成員拟赊,我們需要使用多條服務(wù)器來啟動(dòng)mongo服務(wù)刺桃。
進(jìn)入Mongo客戶端,并使用rs.add()方法來添加副本集的成員吸祟。
rs.add(HOST_NAME:PORT)
實(shí)例:
假設(shè)你已經(jīng)啟動(dòng)了一個(gè)名為 mongod1.net瑟慈,端口號(hào)為27017的Mongo服務(wù)。
在客戶端命令窗口使用rs.add() 命令將其添加到副本集中屋匕,命令如下所示:
rs.add("mongod1.net:27017")
MongoDB 中你只能通過主節(jié)點(diǎn)將Mongo服務(wù)添加到副本集中葛碧, 判斷當(dāng)前運(yùn)行的Mongo服務(wù)是否為主節(jié)點(diǎn)可以使用命令
db.isMaster()
MongoDB的副本集與我們常見的主從有所不同,主從在主機(jī)宕機(jī)后所有服務(wù)將停止过吻,而副本集在主機(jī)宕機(jī)后进泼,副本會(huì)接管主節(jié)點(diǎn)成為主節(jié)點(diǎn)蔗衡,不會(huì)出現(xiàn)宕機(jī)的情況。
MongoDB - 分片
當(dāng)MongoDB存儲(chǔ)海量的數(shù)據(jù)時(shí)乳绕,==一臺(tái)機(jī)器可能不足以存儲(chǔ)數(shù)據(jù)==绞惦,也可能不足以提供可接受的讀寫吞吐量。這時(shí)洋措,我們就可以通過在多臺(tái)機(jī)器上分割數(shù)據(jù)济蝉,使得數(shù)據(jù)庫系統(tǒng)能存儲(chǔ)和處理更多的數(shù)據(jù)。
為什么使用分片菠发?
- 復(fù)制所有的寫入操作到主節(jié)點(diǎn)
- 延遲的敏感數(shù)據(jù)會(huì)在主節(jié)點(diǎn)查詢
- 單個(gè)副本集限制在12個(gè)節(jié)點(diǎn)
- 當(dāng)請求量巨大時(shí)會(huì)出現(xiàn)內(nèi)存不足王滤。
- 本地磁盤不足
- 垂直擴(kuò)展價(jià)格昂貴
分片集群結(jié)構(gòu)
三個(gè)主要組件:
- Shard: 用于存儲(chǔ)實(shí)際的數(shù)據(jù)塊,實(shí)際生產(chǎn)環(huán)境中一個(gè)shard server角色可由幾臺(tái)機(jī)器組個(gè)一個(gè)replica set承擔(dān)滓鸠,防止主機(jī)單點(diǎn)故障
- Config Server: mongod實(shí)例淑仆,存儲(chǔ)了整個(gè) ClusterMetadata,其中包括 chunk信息哥力。
- Query Routers: 前端路由蔗怠,客戶端由此接入,且讓整個(gè)集群看上去像單一數(shù)據(jù)庫吩跋,前端應(yīng)用可以透明使用寞射。
MongoDB - 監(jiān)控
監(jiān)控可以了解 MongoDB 的==運(yùn)行情況==及==性能==
MongoDB中提供了 mongostat 和 mongotop 兩個(gè)命令來監(jiān)控MongoDB的運(yùn)行情況。
mongostat
它會(huì)間隔固定時(shí)間獲取 mongodb 的當(dāng)前運(yùn)行狀態(tài)锌钮,并輸出桥温。
如果你發(fā)現(xiàn)數(shù)據(jù)庫突然變慢或者有其他問題的話,你第一手的操作就考慮采用 mongostat 來查看 mongo 的狀態(tài)梁丘。
mongostat
mongotop
mongotop用來跟蹤MongoDB的實(shí)例侵浸,提供每個(gè)集合的統(tǒng)計(jì)數(shù)據(jù)。默認(rèn)情況下氛谜,mongotop每一秒刷新一次掏觉。
mongotop
輸出結(jié)果字段說明:
- ns:包含數(shù)據(jù)庫命名空間,后者結(jié)合了數(shù)據(jù)庫名稱和集合值漫。
- db:包含數(shù)據(jù)庫的名稱澳腹。名為 . 的數(shù)據(jù)庫針對全局鎖定,而非特定數(shù)據(jù)庫杨何。
- total:mongod花費(fèi)的時(shí)間工作在這個(gè)命名空間提供總額酱塔。
- read:提供了大量的時(shí)間,這mongod花費(fèi)在執(zhí)行讀操作危虱,在此命名空間羊娃。
- write:提供這個(gè)命名空間進(jìn)行寫操作,這mongod花了大量的時(shí)間埃跷。
等待的時(shí)間長度蕊玷,以秒為單位芦瘾,默認(rèn) 1s
mongotop 10
報(bào)告每個(gè)數(shù)據(jù)庫的鎖的使用
mongotop --locks
MongoDB - 備份與恢復(fù)
mongodump
在Mongodb中我們使用 mongodump
命令來備份MongoDB數(shù)據(jù)。
該命令可以導(dǎo)出所有數(shù)據(jù)到指定目錄中集畅。
mongodump命令可以通過參數(shù)指定導(dǎo)出的數(shù)據(jù)量級(jí)轉(zhuǎn)存的服務(wù)器近弟。
mongodump -h dbhost -d dbname -o dbdirectory
-h:MongDB所在服務(wù)器地址,例如:127.0.0.1挺智,當(dāng)然也可以指定端口號(hào):127.0.0.1:27017
-d:需要備份的數(shù)據(jù)庫實(shí)例祷愉,例如:test
-o:備份的數(shù)據(jù)存放位置,例如:c:\data\dump赦颇,當(dāng)然該目錄需要提前建立二鳄,在備份完成后,系統(tǒng)自動(dòng)在dump目錄下建立一個(gè)test目錄媒怯,這個(gè)目錄里面存放該數(shù)據(jù)庫實(shí)例的備份數(shù)據(jù)订讼。
實(shí)例
備份 mongodb_study 數(shù)據(jù)庫中的所有集合到 E:\MongoDB\dump
mongodump -h 127.0.0.1 -d mongodb_study -o E:\MongoDB\dump
不帶任何參數(shù),即在當(dāng)前目錄下備份所有數(shù)據(jù)庫實(shí)例
mongodump
備份所有MongoDB數(shù)據(jù)
mongodump --host HOST_NAME --port PORT_NUMBER
// 如
mongodump --host w3cschool.cc --port 27017
備份指定數(shù)據(jù)庫的集合
mongodump --collection COLLECTION_NAME --db DB_NAME
// 如
mongodump --collection mycol --db test
mongorestore
在Mongodb中我們使用 mongorestore
命令來恢復(fù)MongoDB數(shù)據(jù)扇苞。
mongorestore -h <hostname><:port> -d dbname <path>
--host <:port>, -h <:port>:MongoDB所在服務(wù)器地址欺殿,默認(rèn)為: localhost:27017
--db , -d :需要恢復(fù)的數(shù)據(jù)庫實(shí)例,例如:test鳖敷,當(dāng)然這個(gè)名稱也可以和備份時(shí)候的不一樣脖苏,比如test2
--drop:恢復(fù)的時(shí)候,先刪除當(dāng)前數(shù)據(jù)定踱,然后恢復(fù)備份的數(shù)據(jù)棍潘。就是說,恢復(fù)后崖媚,備份后添加修改的數(shù)據(jù)都會(huì)被刪除亦歉,慎用哦!
<path>:mongorestore 最后的一個(gè)參數(shù)畅哑,設(shè)置備份數(shù)據(jù)所在位置肴楷,例如:c:\data\dump\test。你不能同時(shí)指定 <path> 和 --dir 選項(xiàng)敢课,--dir也可以設(shè)置備份目錄阶祭。
--dir:指定備份的目錄,你不能同時(shí)指定 <path> 和 --dir 選項(xiàng)直秆。
實(shí)例
恢復(fù)存放在 E:\MongoDB\dump 中的數(shù)據(jù)庫 mongodb_study,恢復(fù)前后的數(shù)據(jù)庫名不必相同
mongorestore -h localhost /db mongodb_study /dir E:\MongoDB\dump\mongodb_study
Node.js 連接 MongoDB
與 MySQL 不同的是 MongoDB 會(huì)自動(dòng)創(chuàng)建數(shù)據(jù)庫和集合鞭盟,所以使用前我們不需要手動(dòng)去創(chuàng)建圾结。
安裝驅(qū)動(dòng):npm install mongodb
運(yùn)行 node:node connect
實(shí)例
connect.js
const MongoClient = require('mongodb').MongoClient;
// 自動(dòng)創(chuàng)建數(shù)據(jù)庫 runoob
let mongoConnect = 'mongodb://localhost:27017/runoob';
// 插入數(shù)據(jù),插入到數(shù)據(jù)庫 runoob 的 site 集合中
let insertData = function(db, callback) {
// 自動(dòng)創(chuàng)建集合 site
let collection = db.collection('site');
// 插入文檔
let data = [{
"name": "菜鳥教程",
"url": "www.runoob.com"
}, {
"name": "菜鳥工具",
"url": "c.runoob.com"
}];
collection.insert(data, function(err, result) {
if (err) {
console.log('Error:' + err);
return;
}
callback(result);
});
};
// 刪除數(shù)據(jù)齿诉,刪除所有 name 為 "菜鳥工具" 的文檔
let deleteData = function(db, callback) {
let collection = db.collection('site');
let whereStr = {
"name": "菜鳥工具"
};
collection.remove(whereStr, function(err, result) {
if (err) {
console.log('Error:' + err);
return;
}
callback(result);
});
};
// 修改數(shù)據(jù)筝野,將所以 name 為 "菜鳥教程" 的 url 改為 https://www.runoob.com
let updateData = function(db, callback) {
let collection = db.collection('site');
let whereStr = {
"name": "菜鳥教程"
};
let updateStr = {
$set: {
"url": "https://www.runoob.com"
}
};
collection.update(whereStr, updateStr, {
multi: true
}, function(err, result) {
if (err) {
console.log('Error:' + err);
return;
}
callback(result);
});
};
// 查詢數(shù)據(jù)晌姚,查詢 name 為 "菜鳥教程" 的數(shù)據(jù)
let selectData = function(db, callback) {
let collection = db.collection('site');
let whereStr = {
"name": '菜鳥教程'
};
collection.find(whereStr).toArray(function(err, result) {
if (err) {
console.log('Error:' + err);
return;
}
callback(result);
});
};
MongoClient.connect(mongoConnect, function(err, db) {
console.log("連接成功!");
insertData(db, function(result) {
console.log("插入數(shù)據(jù)成功歇竟!");
console.log(result);
db.close();
});
deleteData(db, function(result) {
console.log("刪除數(shù)據(jù)成功挥唠!");
console.log(result);
db.close();
});
updateData(db, function(result) {
console.log("修改數(shù)據(jù)成功!");
console.log(result);
db.close();
});
selectData(db, function(result) {
console.log("查詢數(shù)據(jù)成功焕议!");
console.log(result);
db.close();
});
});
mongoose
Mongoose學(xué)習(xí)參考文檔——基礎(chǔ)篇:https://cnodejs.org/topic/504b4924e2b84515770103dd
mongoose學(xué)習(xí)筆記:https://cnodejs.org/topic/58b911997872ea0864fee313
mongoose學(xué)習(xí)文檔:http://www.cnblogs.com/y-yxh/p/5689555.html
Nodejs學(xué)習(xí)筆記(十四)— Mongoose介紹和入門:http://www.cnblogs.com/zhongweiv/p/mongoose.html
Mongoose全面理解:http://www.cnblogs.com/jayruan/p/5123754.html
Node.js 有針對 MongoDB 的數(shù)據(jù)庫驅(qū)動(dòng):mongodb宝磨。你可以使用 npm install mongodb
來安裝。不過直接使用 mongodb 模塊雖然強(qiáng)大而靈活盅安,但有些繁瑣唤锉,我就使用 mongoose 吧。
Mongoose 基于nodejs别瞭、構(gòu)建在 mongodb 之上窿祥,使用 javascript 編程,是==連接 mongodb 數(shù)據(jù)庫的軟件包==蝙寨,使mongodb的文檔數(shù)據(jù)模型變的優(yōu)雅起來晒衩,方便對mongodb文檔型數(shù)據(jù)庫的連接和增刪改查等常規(guī)數(shù)據(jù)操作。
mongoose 是當(dāng)前使用 mean(mongodb express angularjs nodejs)全棧開發(fā)必用的連接數(shù)據(jù)庫軟件包墙歪。
==mongoose 浸遗,提供了Schema、Model 和 Document 對象箱亿,用起來更為方便跛锌。== 另外,mongoose 還有 Query 和 Aggregate 對象:Query 實(shí)現(xiàn)查詢届惋、Aggregate 實(shí)現(xiàn)聚合
mongoose 三個(gè)重要概念
Schema髓帽、Model、Entity 的關(guān)系:Schema生成Model脑豹,Model創(chuàng)造Entity郑藏,Model和Entity都可對數(shù)據(jù)庫操作造成影響,但Model比Entity更具操作性瘩欺。
1. Schema 模式
Schema 對象定義==文檔結(jié)構(gòu)==必盖,可以定義字段、類型俱饿、唯一性歌粥、索引、驗(yàn)證等拍埠。
Schema 不僅定義了文檔結(jié)構(gòu)和使用性能失驶,還可以有擴(kuò)展插件、實(shí)例方法枣购、靜態(tài)方法嬉探、復(fù)合索引擦耀、文檔生命周期鉤子
// new mongoose.Schema() 中傳入一個(gè) JSON 對象,定義屬性和屬性類型
var BlogSchema = new mongoose.Schema({
title: String,
author: String
});
有的時(shí)候涩堤,我們創(chuàng)造的 Schema 不僅要為后面的 Model 和 Entity 提供公共的屬性眷蜓,還要提供公共的方法。
2. Model 模型
Model 對象表示集合中的所有文檔
由 Schema 發(fā)布生成的模型胎围,具有抽象屬性和行為的數(shù)據(jù)庫操作對
3. Document 文檔
Document 可等同于 Entity
由 Model 創(chuàng)建的實(shí)體吁系,他的操作也會(huì)影響數(shù)據(jù)庫
使用
- 定義一個(gè) Schema 模式
- 將該 Schema 發(fā)布為 Model
- 用 Model 創(chuàng)建 Entity
- Entity 是具有具體的數(shù)據(jù)庫操作 CRUD 的
mongoose 的 connection 對象定義了一些事件,比如 connected open close error 等痊远,我們可以監(jiān)聽這些事件垮抗。
const mongoose = require('mongoose');
let db = mongoose.connect('mongodb://127.0.0.1:27017/test');
db.connection.on('error', console.error.bind(console, '數(shù)據(jù)庫連接失敗:'));
db.connection.once('open', function() {
console.log('數(shù)據(jù)庫連接成功碧聪!');
// 定義一個(gè) Schema 模式
// new Schema() 中傳入一個(gè) JSON 對象冒版,定義屬性和屬性類型
let PersonSchema = new mongoose.Schema({
name: {
type: String,
unique: true
},
password: String
});
// 將該 Schema 發(fā)布為 Model
let PersonModel = mongoose.model('col_1', PersonSchema);
// 拿到了 Model 對象,就可以執(zhí)行增刪改查等操作了
// 如果要執(zhí)行查詢逞姿,需要依賴 Model另患,當(dāng)然 Entity 也是可以做到的
PersonModel.find(function(err, result) {
// 查詢到的所有person
});
// 用 Model 創(chuàng)建 Entity
let personEntity = new PersonModel({
name: 'Krouky',
password: '10086'
});
// Entity 是具有具體的數(shù)據(jù)庫操作 CRUD 的
// 執(zhí)行完成后队贱,數(shù)據(jù)庫就有該數(shù)據(jù)了
personEntity.save(function(err, result) {
if (err) {
console.log(err);
} else {
console.log(`${result} saved!`);
}
});
});