mongoDB 學(xué)習(xí)筆記純干貨(mongoose疆液、增刪改查、聚合陕贮、索引堕油、連接、備份與恢復(fù)肮之、監(jiān)控等等)

最后更新時(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)行

  1. 下載

07/05/2017 Current Stable Release (3.4.6)

https://www.mongodb.com/download-center#community

  1. 創(chuàng)建數(shù)據(jù)目錄

MongoDB 將數(shù)據(jù)目錄存儲(chǔ)在 db 目錄下搜囱,需手動(dòng)創(chuàng)建丑瞧。

E:\MongoDB\data\db
  1. 運(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
  1. MongoDB 后臺(tái)管理

運(yùn)行 mongo.exe

MongoDB Shell是MongoDB自帶的交互式Javascript shell,用來對MongoDB進(jìn)行操作和管理的交互式環(huán)境扮宠。

  1. 將 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
  1. 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字符娩脾。
image
image

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)一致。

image

復(fù)制設(shè)置

  1. 關(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)

image

三個(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ù)庫

使用

  1. 定義一個(gè) Schema 模式
  2. 將該 Schema 發(fā)布為 Model
  3. 用 Model 創(chuàng)建 Entity
  4. 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!`);
        }
    });
});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蜒车,一起剝皮案震驚了整個(gè)濱河市勃刨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谒养,老刑警劉巖挺狰,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異买窟,居然都是意外死亡丰泊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門始绍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瞳购,“玉大人,你說我怎么就攤上這事亏推⊙” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵吞杭,是天一觀的道長盏浇。 經(jīng)常有香客問我,道長篇亭,這世上最難降的妖魔是什么缠捌? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮译蒂,結(jié)果婚禮上曼月,老公的妹妹穿的比我還像新娘。我一直安慰自己柔昼,他們只是感情好哑芹,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捕透,像睡著了一般聪姿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上乙嘀,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天末购,我揣著相機(jī)與錄音,去河邊找鬼虎谢。 笑死盟榴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的婴噩。 我是一名探鬼主播擎场,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼几莽!你這毒婦竟也來了迅办?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對情侶失蹤章蚣,失蹤者是張志新(化名)和其女友劉穎站欺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纤垂,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡矾策,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了洒忧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝴韭。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖熙侍,靈堂內(nèi)的尸體忽然破棺而出榄鉴,到底是詐尸還是另有隱情,我是刑警寧澤蛉抓,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布庆尘,位于F島的核電站,受9級(jí)特大地震影響巷送,放射性物質(zhì)發(fā)生泄漏驶忌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望付魔。 院中可真熱鬧聊品,春花似錦、人聲如沸几苍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妻坝。三九已至伸眶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刽宪,已是汗流浹背厘贼。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留圣拄,地道東北人嘴秸。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像售担,于是被迫代替她去往敵國和親赁遗。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容