MongoDB 入門教程

1.MongoDB 簡介

MongoDB 是由C++語言編寫的,是一個基於 分佈式文件存儲的開源數據庫系統。
在高負載的狀況下,添加更多的節點,能夠保證服務器性能。
MongoDB 旨在爲WEB應用提供可擴展的高性能數據存儲解決方案。
MongoDB 將數據存儲爲一個 文檔,數據結構由 鍵值(key=>value)對組成。MongoDB 文檔相似於JSON對象。字段值能夠包含其餘文檔,數組及文檔數組。

2. MongoDB 術語概念

MongoDB 和關係型數據庫相關概念關係對照表:php

SQL術語/概念 MongoDB術語/概念 解釋/說明
database database 數據庫
table collection 數據庫表/集合
row document 數據記錄行/文檔
column field 數據字段/域
index index 索引
table joins 錶鏈接,MongoDB不支持
primary key primary key 主鍵,MongoDB自動將_id字段設置爲主鍵

3. MongoDB shell 經常使用命令

use DATABASE_NAME :若是數據庫不存在,則建立數據庫,不然切換到指定數據庫
db.getName()db:當前正在使用的數據庫
show dbs:查詢全部數據庫
db.dropDatabase():刪除當前數據庫,默認爲 test。其餘庫先切換。
db.collection.drop():刪除集合。collection爲集合名稱。
show tablesshow collection :查詢當前庫下全部集合。
db.createCollection(name, options):建立集合。 name: 要建立的集合名稱; options: 可選參數, 指定有關內存大小及索引的選項.例:db.createCollection("runoob")

若是 mongo shell不接受集合的名稱,例如若是名稱中包含空格,連字符」-「,或者以數字開始,你可使用代替語法來指代集合,以下所示:html

>db["3test"].find()

db.getCollection("3test").find()

db.stats() 查看數據庫使用狀態的統計信息。linux

>db.stats() 
{
"db":"test",
--查看的是哪一個數據庫
"collections":7,
--collection數量
"objects":28,
--當前數據庫中全部集合中的對象數(即文檔)的數量。
"avgObjSize":50.57142857142857,
--對象平均大小,以字節爲單位
"dataSize":1416,
--數據大小
"storageSize":31744,
--數據大小(含預分配空間)
"numExtents":7,
--事件數量
"indexes":7,
--索引數量
"indexSize":57344,
--索引大小
"fileSize":50331648,
--文件大小
"ok":1
--本次取stats是否正常
}

4. MongoDB CURD

  • 插入(Create)

簡述:文檔的數據結構和JSON基本同樣。全部存儲在集合中的數據都是BSON格式。是一種類json的一種二進制形式的存儲格式,簡稱Binary JSON。命令格式以下:
db.COLLECTION_NAME.insert(document)git

例:
    >db.col.insert({title: 'MongoDB 教程', 
    description: 'MongoDB 是一個 Nosql 數據庫',
    by: '菜鳥教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
})

插入的時候若是集合不存在,那麼插入操做會建立集合。github

_id 字段:在MongoDB中,存儲於集合中的每個文檔都須要一個惟一的 _id 字段做爲 primary_key。若是一個插入文檔操做遺漏了_id 字段,MongoDB驅動會自動爲_id字段生成一個 ObjectId
這種狀況一樣適用於經過帶有參數 upsert: true 的update操做來插入文檔的狀況。sql

ObjectId
MongoDB採用了一個稱之爲ObjectId的類型來作主鍵。ObjectId是一個12字節的 BSON 類型字符串,BSON字符串都是UTF-8編碼。按照字節順序,從開頭依次表示:mongodb

  • 4字節:UNIX時間戳
  • 3字節:表示運行MongoDB的機器的標識符
  • 2字節:表示生成此_id的進程
  • 3字節:由一個隨機數開始的計數器生成的值

db.collection.insertOne() : 向集合插入單個文檔。
db.collection.insertMany(): 向集合插入多個文檔。shell

  • 更新(Update)

命令格式以下:數據庫

db.collection.update(
   <query>, // update的查詢條件,相似sql update查詢內where後面的。
   <update>, //update的對象和一些更新的操做符(如$,$inc...)等,也能夠理解爲sql update 查詢內set後面的
   {
     upsert: <boolean>, //可選,這個參數的意思是,若是不存在'update的記錄,是否插入objNew,true爲插入,默認是false,不插入
     multi: <boolean>, // 可選,mongodb 默認是false,只更新找到的第一條記錄,若是這個參數爲true,就把按條件查出來多條記錄所有更新。
     writeConcern: <document> //可選,拋出異常的級別。
   }
)

示例:
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})更新一條數據標題(title)。json

默認狀況下, db.collection.update() 只更新一個文檔。要更新多個文檔,請使用 multi 選項設置 multi 參數爲 true。

save() 方法經過傳入的文檔來替換已有文檔。語法格式以下:

db.collection.save(
   <document>,//文檔數據。
   {
     writeConcern: <document> //可選,拋出異常的級別。
   }
)
_id 字段一旦設定,你不能更新 _id 字段的值,你也不能用有不一樣 _id 字段值的替換文檔來替換已經存在的文檔。

其餘命令:
db.collection.updateOne()即便可能有多個文檔經過過濾條件匹配到,可是也最多也只更新一個文檔。
db.collection.updateMany()更新全部經過過濾條件匹配到的文檔。
db.collection.replaceOne()即便可能有多個文檔經過過濾條件匹配到,可是也最多也只替換一個文檔。

  • 查詢(Retrieve)

    db.collection.find(query, projection) 方法從集合中讀取文檔,省略過濾條件則是查詢全部文檔;collection是文檔名稱。
    query :可選,使用查詢操做符指定查詢條件
    projection :可選,使用投影操做符指定返回的鍵。查詢時返回文檔中全部鍵值, 只需省略該參數便可(默認省略)。

db.collection.find().pretty()pretty()方法以格式化的方式來顯示全部文檔。

除了 find() 方法以外,還有一個 findOne() 方法,它只返回一個文檔。

MongoDB 與 RDBMS Where 語句比較

操做 格式 範例 RDBMS中的相似語句
等於 {<key>:<value>} db.col.find({"by":"菜鳥教程"}).pretty() where by = '菜鳥教程'
小於 {<key>:{$lt:<value>}} db.col.find({"likes":{$lt:50}}).pretty() where likes < 50
小於或等於 {<key>:{$lte:<value>}} db.col.find({"likes":{$lte:50}}).pretty() where likes <= 50
大於 {<key>:{$gt:<value>}} db.col.find({"likes":{$gt:50}}).pretty() where likes > 50
大於或等於 {<key>:{$gte:<value>}} db.col.find({"likes":{$gte:50}}).pretty() where likes >= 50
不等於 {<key>:{$ne:<value>}} db.col.find({"likes":{$ne:50}}).pretty() where likes != 50
包含 {<key>:{$in:[a,b,c]} db.col.find("likes":{$in:[2,4,6]}).pretty() where likes in(2,4,6)
不包含 {<key>:{$nin:[a,b,c]} db.col.find("likes":{$nin:[2,4,6]}).pretty() where likes not in(2,4,6)

MongoDB AND 條件
find() 方法能夠傳入多個鍵(key),每一個鍵(key)以逗號隔開,即常規 SQL 的 AND 條件。

db.col.find(
    {
        "by":"菜鳥教程",
         "title":"MongoDB 教程"
    }
).pretty()

MongoDB OR 條件
OR 條件語句使用了關鍵字 $or,語法格式以下

>db.col.find(
   {
      $or: [
         {key1: value1}, {key2:value2}
      ]
   }
).pretty()
>db.col.find(
 {
    $or:[
        {"by":"菜鳥教程"},
        {"title": "MongoDB 教程"}
     ]
  }
).pretty()

AND 和 OR 聯合使用

>db.col.find(
    {"likes": 
        {$gt:50}, 
        $or: [
            {"by": "菜鳥教程"},
            {"title": "MongoDB 教程"}
         ]
    }
 ).pretty()

projection 參數的使用方法

db.collection.find(query, projection)

若不指定 projection,則默認返回全部鍵,指定 projection 格式以下,有兩種模式

  • db.collection.find(query, {title: 1, by: 1}) // inclusion模式 指定返回的鍵,不返回其餘鍵
  • db.collection.find(query, {title: 0, by: 0}) // exclusion模式 指定不返回的鍵,返回其餘鍵

_id 鍵默認返回,須要主動指定 _id:0 纔會隱藏

兩種模式不可混用(由於這樣的話沒法推斷其餘鍵是否應返回)

db.collection.find(query, {title: 1, by: 0}) // 錯誤

只能全1或全0,除了在inclusion模式時能夠指定_id爲0

db.collection.find(query, {_id:0, title: 1, by: 1}) // 正確

  • 刪除(Delete)

MongoDB remove()函數是用來移除集合中的數據。在執行remove()函數前先執行find()命令來判斷執行的條件是否正確,這是一個比較好的習慣。
remove() 方法的基本語法格式以下所示:

db.collection.remove(
   <query>, //(可選)刪除的文檔的條件。
   {
     justOne: <boolean>, //(可選)若是設爲 true 或 1,則只刪除一個文檔。
     writeConcern: <document> //(可選)拋出異常的級別。
   }
)

如今官方推薦使用 deleteOne()deleteMany() 方法。
db.inventory.deleteMany({}):刪除集合下所有文檔。

例如:

刪除 status 等於 A 的所有文檔:
    db.inventory.deleteMany({ status : "A" })
刪除 status 等於 D 的一個文檔:
    db.inventory.deleteOne( { status: "D" } )

5. Windows 下的配置文件及 mongo 進程

安裝完成以後,Windows下是不會自動生成配置文件,也沒有進程。

新建配置文件

  • 在mongodb的安裝目錄下,如 C:\Program Files\MongoDB\Server\3.6 新建conf目錄並新建mongod.conf文件,配置內容以下:
systemLog: #日誌文件
   destination: file
   path: F:\mongoDB\logs\mongod.log
   logAppend: true
storage: #數據存儲路徑
   dbPath: F:\data\db
   journal:
     enabled: true
net:#綁定ip及端口
   bindIp: 127.0.0.1
   port: 27017
setParameter:
   enableLocalhostAuthBypass: true  
#security:#安全認證
 #authorization: enabled

log文件也是不存在的,根據本身的須要在相應的目錄下新建mongod.log文件。

開啓認證及生成守護進程
mongod --auth --config "C:\Program Files\MongoDB\Server\3.6\conf\mongod.conf" --install --serviceName "MongoD
--auth : 開啓認證
--serviceName "MongoDB":生成名稱爲MongoDB的守護進程


6. 設置帳戶密碼

特別注意:賬號是跟着庫走的,因此在指定庫裏受權,必須也在指定庫裏驗證(auth)。

配置以前先配置文件不要開啓auth認證,默認爲關閉狀態。不然進入查看數據庫會權限不足。

命令行下執行 `mongo 進入數據庫
use admin 進入admin庫
db.getUsers() 可查看當前庫用戶列表
執行 db.createUser({ user: "admin", pwd: "admin", roles: [{ role: "userAdminAnyDatabase", db: "admin" }] }) 新建用戶設置帳戶密碼,並指定級別。

clipboard.png

關於受權:

  • roles:指定用戶的角色,能夠用一個空數組給新用戶設定空角色;在roles字段,能夠指定內置角色和用戶定義的角色。

    • **role裏的可選角色**

      • Built-In Roles(內置角色)

        1. 數據庫用戶角色:read、readWrite;
        2. 數據庫管理角色:dbAdmin、dbOwner、userAdmin;
        3. 集羣管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
        4. 備份恢復角色:backup、restore;
        5. 全部數據庫角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
        6. 超級用戶角色:root (有幾個角色間接或直接提供了系統超級用戶的訪問(dbOwner 、userAdmin、userAdminAnyDatabase))
        7. 內部角色:__system
      • 具體角色權限

        Read:容許用戶讀取指定數據庫
        readWrite:容許用戶讀寫指定數據庫
        dbAdmin:容許用戶在指定數據庫中執行管理函數,如索引建立、刪除,查看統計或訪問system.profile
        userAdmin:容許用戶向system.users集合寫入,能夠找指定數據庫裏建立、刪除和管理用戶
        clusterAdmin:只在admin數據庫中可用,賦予用戶全部分片和複製集相關函數的管理權限。
        readAnyDatabase:只在admin數據庫中可用,賦予用戶全部數據庫的讀權限
        readWriteAnyDatabase:只在admin數據庫中可用,賦予用戶全部數據庫的讀寫權限
        userAdminAnyDatabase:只在admin數據庫中可用,賦予用戶全部數據庫的userAdmin權限
        dbAdminAnyDatabase:只在admin數據庫中可用,賦予用戶全部數據庫的dbAdmin權限。
        root:只在admin數據庫中可用。超級帳號,超級權限

修改配置文件:sudo vim /etc/mongodb.conf

security:
  authorization: enabled 
//注意縮進,縮進參照配置文件其餘配置。縮進錯誤可能重啓不成功

去掉前面的 # 號。

重啓mongo服務

/etc/init.d/mongodb restart

從新進入數據庫,發現命令沒法執行,報權限不足錯誤。切換到admin庫use admin(哪裏建立的用戶切換到哪一個庫),執行db.auth("admin","admin") 返回1,是認證成功。命令能夠正常執行。

clipboard.png

注意:MongoDB建立用戶在命令行下,而且制定用戶能夠操做那些庫

7. PHP鏈接MongoDB

Windows 安裝 MongoDB PHP擴展
MongoDB PHP擴展下載地址
'Thread safe'(線程安全)是運行在Apache上以模塊的PHP上,若是你以CGI的模式運行PHP,請選擇非線程安全模式(' non-thread safe')。
版本選擇參考:

clipboard.png

clipboard.png

下載完你須要的二進制包後,解壓壓縮包,將'php_mongo.dll'文件添加到你的PHP擴展目錄中(ext)。ext目錄一般在PHP安裝目錄下的ext目錄。而後php.ini中打開

clipboard.png

重啓服務器。

經過瀏覽器訪問phpinfo,若是安裝成功,就會看到類型如下的信息:

clipboard.png

Linux上安裝 MongoDB PHP擴展
linux中執行如下命令來安裝MongoDB 的 PHP7 擴展驅動

$ /usr/local/php7/bin/pecl install mongodb

執行成功後,會輸出如下結果:

……
Build process completed successfully
Installing '/usr/local/php7/lib/php/extensions/no-debug-non-zts-20151012/mongodb.so'
install ok: channel://pecl.php.net/mongodb-1.1.7
configuration option "php_ini" is not set to php.ini location
You should add "extension=mongodb.so" to php.ini

下來咱們打開 php.ini 文件,添加 extension=mongodb.so 配置。

能夠直接執行如下命令來添加。

$ echo "extension=mongodb.so" >> `/usr/local/php7/bin/php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
注意:以上執行的命令中 php7 的安裝目錄爲 /usr/local/php7/,若是你安裝在其餘目錄,須要相應修改 pecl 與 php 命令的路徑。 使用php的 pecl安裝命令必須保證網絡鏈接可用以及root權限。

若是你的php是本身編譯的,則安裝方法以下(假設是編譯在/usr/local/php目錄中) github地址

$ git clone https://github.com/mongodb/mongo-php-driver.git
$ cd mongo-php-driver
$ git submodule sync && git submodule update --init
$ /usr/local/php/bin/phpize
$ ./configure --with-php-config=/usr/local/php/bin/php-config
$ make all -j 5
$ sudo make install

執行以上命令後,你須要修改php.ini文件,在php.ini文件中添加mongo配置,
配置以下: extension=mongo.so
注意:你須要指明 extension_dir 配置項的路徑。

php例子:

<?php
//鏈接數據庫
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");  

// 插入數據,BulkWrite是批量插入
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert(['x' => 1, 'name'=>'菜鳥教程', 'url' => 'http://www.runoob.com']);
$bulk->insert(['x' => 2, 'name'=>'Google', 'url' => 'http://www.google.com']);
$bulk->insert(['x' => 3, 'name'=>'taobao', 'url' => 'http://www.taobao.com']);
$manager->executeBulkWrite('test.sites', $bulk);

$filter = ['x' => ['$gt' => 1]]; //字段名及匹配條件
$options = [
    'projection' => ['_id' => 0], // 指定返回鍵,參考上面**projection用法**
    'sort' => ['x' => -1], //排序字段,1是正序,-1是倒序
];

// 查詢數據
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $manager->executeQuery('test.sites', $query);

foreach ($cursor as $document) {
    print_r($document);
}
?>

8. MongoDB備份與恢復

在Mongodb中咱們使用mongodump命令來備份MongoDB數據。該命令能夠導出全部數據到指定目錄中。

> mongodump -h HOST_NAME -d DB_NAME -o BACKUP_DIRECTORY
> mongodump --host HOST_NAME --port PORT_NUMBER -d DB_NAME -o BACKUP_DIRECTORY

示例:備份單庫

vagrant@homestead:~$ mongodump -h 127.0.0.1 -d DB_NAME -o /root/dbBackup/mongoDB/dbBackupName_$(date +"%Y-%m-%d_%H")

也能夠備份指定文檔:
> mongodump -h dbhost --collection COLLECTION -d DB_NAME -o BACKUP_DIRECTORY

mongodb使用 mongorestore 命令來恢復備份的數據。
>mongorestore -h <hostname><:port> -d dbname <path>

--host <:port>, -h <:port>:
MongoDB所在服務器地址,默認爲: localhost:27017
--db , -d
須要恢復的數據庫實例,例如:test,固然這個名稱也能夠和備份時候的不同,好比test2
--drop
恢復的時候,先刪除當前數據,而後恢復備份的數據。就是說,恢復後,這份備份文件以後添加或修改的數據都會被刪除,慎用哦!
<path>
mongorestore 最後的一個參數,設置備份數據所在位置,例如:c:datadumptest。
你不能同時指定 <path> 和 --dir 選項,--dir也能夠設置備份目錄。
--dir
指定備份的目錄
你不能同時指定 <path> 和 --dir 選項。

示例:

vagrant@homestead:~$ /usr/local/mongodb/bin/mongodump -h 127.0.0.1:27117 -u USER_NAME -p PASSWORD  -d DB_NAME -o /BACK_DIRECTORY/BACKUP_DB_NAME

9. 錯誤

  • 沒有 phpize 命令

執行: sudo apt install php7.2-dev

  • 錯誤:

The SCRAM_SHA_1 authentication mechanism requires libmongoc built with ENABLE_SSL

方法:

sudo apt-get install -y libcurl4-openssl-dev pkg-config libssl-dev
sudo pecl install mongodb

安裝後別忘記在 php.ini 中添加 extension=mongodb.so

重啓:sudo service php7.2-fpm restart


參考:菜鳥教程
MongoDB中文社區
MongoDB官方文檔

相關文章
相關標籤/搜索