MongoDB 入門
一、 MongoDB簡介
MongoDB是一個面向文檔的數據庫系統。使用C++編寫,不支持SQL,但有自己功能強大的查詢語法。
MongoDB使用BSON作為數據存儲和傳輸的格式。BSON是一種類似JSON的二進制序列化文檔,支持嵌套對象和數組。
MongoDB很像MySQL,document對應MySQL的row,collection對應MySQL的table。
二、 Windows下MongoDB操作
MongoDB在Windows上的安裝運行很方便。直接下載、解壓,然后運行bin/mongod 即可啟動服務器,運行bin/mongo 即可運行命令行客戶端。
2-1、 下載與解壓
項目主頁:http://www.mongodb.org/downloads。
下載對于版本,解壓并抽取相關的bin目錄到C:\MongoDB下(這個任意選擇)。
在啟動MongoDB之前,我們必須新建一個存放mongoDB數據和日志的目錄。數據庫目錄:C:\MongoDB\data\db\,日志目錄:C:\MongoDB\data\。

2-2、 運行服務端
打開CMD窗口,進入到C:\MongoDB\bin目錄下,運行服務端mongod.exe
C:\>cd C:\MongoDB\bin C:\MongoDB\bin>mongod.exe --dbpath=C:\MongoDB\data\db --directoryperdb --logpath =C:\MongoDB\data\logs --logappend解釋如下:
日志文件為C:\MongoDB\data\logs,以及添加方式記錄(追加)。
數據目錄為C:\MongoDB\data\db,并且每個數據庫將儲存在一個單獨的目錄(--directoryperdb)。

服務端要一直運行。Ctrl+C可中斷。
一般來說,如果覺得很麻煩,可以只指定--dbpath即可,如:
mongod.exe --dbpath=C:\MongoDB\data
2-3、 運行客戶端
再打開一個CMD窗口,進入到C:\MongoDB\bin目錄下,運行客戶端mongo.exe來登錄MongoDB。(要保持服務端mongod.exe的窗口不關閉)

解釋:
運行mongo啟動shell
shell會在啟動時自動連接MongoDB服務器,默認連接test數據庫,并將這個數據庫連接賦值給全局變量db,這個變量是MongoDB的主要入口點。
shell是功能完備的Javascript解釋器,可以運行任何Javascript程序。
我們可以測試一下:

還可以充分利用Javascript的庫,如
![]()
![]()
2-4、 測試操作
MongoDB使用GridFS來儲存大文件。每個BSON對象大小不能超過4MB。
字段名限制:不能以“$”開頭;不能包含“.”;“_id”是系統保留的字段,但用戶可以自己儲存唯一性的數據在字段中。
MongoDB為每個數據庫分配一系列文件。每個數據文件都會被預分配一個大小,第一個文件名字為“.0”,大小為64MB,第二個文件“.1”為128MB,依此類推,文件大小上限為2GB。如下:
![]()
![]()
基本概念:
MongoDB有databases(相當于Mysql的數據庫)組成,databases有collections組成(collection相當于Mysql的表) collections有documents組成(document相當于Mysql的行),documents由fields組成(fields相當于Mysql的列)
MongoDB沒有新建數據庫的命令,只要進行insert或其它操作,MongoDB就會自動幫你建立數據庫和collection。當查詢一個不存在的collection時也不會出錯,Mongo會認為那是一個空的collection。
一個對象被插入到數據庫中時,如果它沒有ID,會自動生成一個“_id”字段,為12字節(24位)16進制數。
那么_id是如何產生的呢?
12字節按照如下方式產生:
![]()
前4個字節是從標準紀元開始的時間戳,單位為妙
#時間戳與隨后的5個字節組合起來,提供了秒級別的唯一性
#接下來的3個字節是所在主機的唯一標識符。通常是極其主機名的散列值->>是不同主機生成不同的_id
#下面的兩個字節來自于進程標識符(PID)->>確保同一機器并發的多個進程產生不同的_id
#前9個字節保證了,同一秒鐘不同機器不同進程產生的_id唯一,后3個字節就是一個計數器,確保相同進程同一秒產生的_id也唯一。
同一秒鐘最多允許每個進程擁有256的3次方個不同的_id
當然如果插入文檔不帶_id,則系統會幫你自動創建一個,如果自己指定了就用自己指定的。
Mongon命令行客戶端的腳本語法:
show dbs // 列出所有數據庫
use memo // 使用數據庫memo。即使這個數據庫不存在也可以執行,但該數據庫不會立刻被新建,要等到執行了insert等的操作時,才會建立這個數據庫。
show collections // 列出當前數據庫的collections(當前數據庫下的表)
db // 顯示當前數據庫
show users // 列出用戶

新建數據庫與數據集合:

show dbs可以看到當前數據庫有admin,local,test 介紹如下:
admin:從權限角度來看,這是‘root'數據庫.要是將一個用戶添加到這個數據庫,這個用戶自動繼承所有數據庫的權限。
有些服務器命令也只能從這個數據庫運行,如關閉服務器
local:這個數據庫永遠不會被復制,可以用來存儲于本地單臺服務器的任意集合
test:客戶端啟動時自動連接到這個數據庫,所以開始db指向的是test
##use test2 ->>此時db指向test2 db.createCollection('t_test')->創建collection(即相當于在數據庫test2中新建t_test表),用show collections //可查看到新建的test2
插入數據:(插入數據的方式有很豐富)
###db.XXX.save():

###db.XXX.insert()
查詢數據:
$lt ->less then 小于
$lte ->less than and equal 不大于
$gt ->greater then 大于
$gte ->greater then and equal 不小于
$ne ->not equal 不等于
MongoDB的查詢語法很強大,類似于SQL的條件查詢。例如,很多SQL可以做的,它都可以做:
db.foo.find() // select * from foo
db.foo.find().limit(10) // select * from foo limit 10
db.foo.find().sort({x:1}) // select * from foo order by x asc 1:升序 -1:降序
db.foo.find().sort({x:1}).skip(5).limit(10) // select * from foo order by x asc limit 5, 10
db.foo.find({x:10}) // select * from foo where x = 10
db.foo.find({x: {$lt:10}}) // select * from foo where x <= 10
db.foo.find({}, {y:true}) // select y from foo
一些SQL不能做的,MongoDB也可以做:
db.foo.find({"address.city":"gz"}) // 搜索嵌套文檔address中city值為gz的記錄
db.foo.find({likes:"math"}) // 搜索數組
db.foo.ensureIndex({"address.city":1}) // 在嵌套文檔的字段上建索引
更新數據:
db.foo.update({},{})更新對象,第一個參數是查詢對象,第二個是替代的,可以在第二個對象里指定更新哪些字段,要使用$set。
"$set"用來指定一個鍵的值。如果這個鍵不存在,則創建它,如果存在則更新

刪除條件查詢:

刪除數據集合(表):

刪除當前數據庫:

db.foo.remove()是用來刪除數據,只刪除匹配的對象
增加field:
$push:增加數組元素
如下面people集合笨沒有addr field,使用$push添加->>如果沒有addr就增加addr field,如果有了,就增加數組元素

$pop:減少數組元素

or,and和exists的用法:

解釋如下:
> db.people.find({"name":"yhb",$or:[{"age":18},{"age":20}]}) //找出name為yhb,age為18或者20的
db.people.find({"addr":{$exists:false}}) //找出不存在addr field
來點復雜的吧:
找出people中name為yhb,年齡為18,或者name為lwy,name為19的

解釋一下:
db.people.find({$or:[{"name":"yhb","age":18},{"name":"lwy","age":19}]}) //{"name":"yhb","age":18}其實就是and的關系
db.people.find({$or:[{$and:[{"name":"yhb"},{"age":18}]},{$and:[{"name":"lwy"},{"age":19}]}]}) //用and明說了一下,其實是一樣的
主要就是注意用法就好了,就是嵌套而已
如果是or: ->> {$or:[{條件1},{條件2}]}
如果是and: ->> {$and:[{條件1},{條件2}]}
索引:
db.foo.ensureIndex({productid:1}) // 在productid上建立普通索引
db.foo.ensureIndex({district:1, plate:1}) // 多字段索引
db.foo.ensureIndex({productid:1}, {unique:true}) // 唯一索引
總的來說,使用mongodb可以滿足常見的增刪改差,但是不能完成復雜的跨表級聯查詢,mongodb努力使數據變得簡單緊湊。
2-5、 備份與恢復
二進制數據格式,常用于備份、還原。
Mongodb的備份工具 mongodump:

事例:下圖把備份數據庫test中所有的數據集合(表)

MongoDB的數據恢復工具 mongorestore:

事例:恢復數據庫test中的表t002的數據

2-6、 數據導出、導入
json或cs v格式,每次一個collection
數據導出:



數據導入:


2-7、 安全與認證
use test2 // 選擇數據庫test2
db.addUser("username", "password"); // 普通權限,可讀寫
db.addUser("username", "password", true); // 只可讀,不可寫
db.system.users.remove({user: “username”}); // 刪除用戶


現在重啟服務器,加入--auth選項,開啟安全檢查
然后用客戶端連接:

注意:那個用哪個數據庫的賬號認證就必須先切換到對應的數據庫