關於MongoDB數據庫的總結

既然要說MongoDB數據庫,先引入NoSQL的概念。java

NoSQL:

NoSQL,指的是非關係型的數據庫。NoSQL有時也稱做Not Only SQL的縮寫,是對不一樣於傳統的關係型數據庫的數據庫管理系統的統稱。node

NoSQL用於超大規模數據的存儲。(例如谷歌或Facebook天天爲他們的用戶收集萬億比特的數據)。這些類型的數據存儲不須要固定的模式,無需多餘操做就能夠橫向擴展。c++

爲何使用NoSQL ?

今天咱們能夠經過第三方平臺(如:Google,Facebook等)能夠很容易的訪問和抓取數據。用戶的我的信息,社交網絡,地理位置,用戶生成的數據和用戶操做日誌已經成倍的增長。咱們若是要對這些用戶數據進行挖掘,那SQL數據庫已經不適合這些應用了, NoSQL數據庫的發展也卻能很好的處理這些大的數據。
正則表達式

什麼是MongoDB ?

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

主要特色:

  • MongoDB 是一個面向文檔存儲的數據庫,操做起來比較簡單和容易。
  • 你能夠在MongoDB記錄中設置任何屬性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")來實現更快的排序。
  • 你能夠經過本地或者網絡建立數據鏡像,這使得MongoDB有更強的擴展性。
  • 若是負載的增長(須要更多的存儲空間和更強的處理能力) ,它能夠分佈在計算機網絡中的其餘節點上這就是所謂的分片。
  • Mongo支持豐富的查詢表達式。查詢指令使用JSON形式的標記,可輕易查詢文檔中內嵌的對象及數組。
  • MongoDb 使用update()命令能夠實現替換完成的文檔(數據)或者一些指定的數據字段 。
  • Mongodb中的Map/reduce主要是用來對數據進行批量處理和聚合操做。
  • Map和Reduce。Map函數調用emit(key,value)遍歷集合中全部的記錄,將key與value傳給Reduce函數進行處理。Map函數和Reduce函數是使用Javascript編寫的,並能夠經過db.runCommand或mapreduce命令來執行MapReduce操做。
  • GridFS是MongoDB中的一個內置功能,能夠用於存放大量小文件。
  • MongoDB容許在服務端執行腳本,能夠用Javascript編寫某個函數,直接在服務端執行,也能夠把函數的定義存儲在服務端,下次直接調用便可。
  • MongoDB支持各類編程語言:RUBY,PYTHON,JAVA,C++,PHP,C#等多種語言。
  • MongoDB安裝簡單。

語言支持

c c++ C# / .NET
Erlang Haskell java
JavaScript Lisp node.JS
Perl PHP Python
Ruby Scala

MongoDB 概念解析

無論咱們學習什麼數據庫都應該學習其中的基礎概念,在mongodb中基本的概念是文檔、集合、數據庫,下面咱們挨個介紹。sql

  • 下表將幫助您更容易理解Mongo中的一些概念:
SQL術語/概念 MongoDB術語/概念 解釋/說明
database database 數據庫
table collection 數據庫表/集合
row document 數據記錄行/文檔
column field 數據字段/域
index index 索引
table joins 錶鏈接,MongoDB不支持
primary key primary key 主鍵,MongoDB自動將_id字段設置爲主鍵

數據庫:

一個mongodb中能夠創建多個數據庫。mongodb

MongoDB的默認數據庫爲"db",該數據庫存儲在data目錄中。數據庫

MongoDB的單個實例能夠容納多個獨立的數據庫,每個都有本身的集合和權限,不一樣的數據庫也放置在不一樣的文件中。express

"show dbs" 命令能夠顯示全部數據的列表。
編程

執行 "db" 命令能夠顯示當前數據庫對象或集合。
數組

運行"use"命令,能夠鏈接到一個指定的數據庫。

數據庫也經過名字來標識。數據庫名能夠是知足如下條件的任意UTF-8字符串。

  • 不能是空字符串("")。
  • 不得含有' '(空格)、.、$、/、\和\0 (空字符)。
  • 應所有小寫。
  • 最多64字節。

有一些數據庫名是保留的,能夠直接訪問這些有特殊做用的數據庫。

  • admin: 從權限的角度來看,這是"root"數據庫。要是將一個用戶添加到這個數據庫,這個用戶自動繼承全部數據庫的權限。一些特定的服務器端命令也只能從這個數據庫運行,好比列出全部的數據庫或者關閉服務器。
  • local: 這個數據永遠不會被複制,能夠用來存儲限於本地單臺服務器的任意集合
  • config: 當Mongo用於分片設置時,config數據庫在內部使用,用於保存分片的相關信息。

文檔:

文檔是一組鍵值(key-value)對(即BSON)。MongoDB 的文檔不須要設置相同的字段,而且相同的字段不須要相同的數據類型,這與關係型數據庫有很大的區別,也是 MongoDB 很是突出的特色。

{"url":"https://www.baidu.com", "name":"百度"}

RDBMS 與 MongoDB 對應的術語:

RDBMS MongoDB
數據庫 數據庫
表格 集合
文檔
字段
表聯合 嵌入文檔
主鍵 主鍵 (MongoDB 提供了 key 爲 _id )

須要注意的是:

  1. 文檔中的鍵/值對是有序的。
  2. 文檔中的值不只能夠是在雙引號裏面的字符串,還能夠是其餘幾種數據類型(甚至能夠是整個嵌入的文檔)。
  3. MongoDB區分類型和大小寫。
  4. MongoDB的文檔不能有重複的鍵。
  5. 文檔的鍵是字符串。除了少數例外狀況,鍵可使用任意UTF-8字符。

集合:

集合就是 MongoDB 文檔組,相似於 RDBMS (關係數據庫管理系統:Relational Database Management System)中的表格。

集合存在於數據庫中,集合沒有固定的結構,這意味着你在對集合能夠插入不一樣格式和類型的數據,但一般狀況下咱們插入集合的數據都會有必定的關聯性。

{"site":"www.baidu.com"}
{"site":"www.google.com","name":"Google"}
{"site":"http://jikedaohang.com","name":"極客導航","num":5}
  • 當第一個文檔插入時,集合就會被建立。

合法的集合名

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),這個字符表示集合名的結尾。
  • 集合名不能以"system."開頭,這是爲系統集合保留的前綴。
  • 用戶建立的集合名字不能含有保留字符。有些驅動程序的確支持在集合名裏面包含,這是由於某些系統生成的集合中包含該字符。除非你要訪問這種系統建立的集合,不然千萬不要在名字裏出現$。 

元數據:

數據庫的信息是存儲在集合中。它們使用了系統的命名空間:

dbname.system.*

在MongoDB數據庫中名字空間 .system.* 是包含多種系統信息的特殊集合(Collection),以下:

集合命名空間 描述
dbname.system.namespaces 列出全部名字空間。
dbname.system.indexes 列出全部索引。
dbname.system.profile 包含數據庫概要(profile)信息。
dbname.system.users 列出全部可訪問數據庫的用戶。
dbname.local.sources 包含複製對端(slave)的服務器信息和狀態。

對於修改系統集合中的對象有以下限制:

  • 在{{system.indexes}}插入數據,能夠建立索引。但除此以外該表信息是不可變的(特殊的drop index命令將自動更新相關信息)。
  • {{system.users}}是可修改的。 {{system.profile}}是可刪除的。

MongoDB 數據類型:

數據類型 描述
String 字符串。存儲數據經常使用的數據類型。在 MongoDB 中,UTF-8 編碼的字符串纔是合法的。
Integer 整型數值。用於存儲數值。根據你所採用的服務器,可分爲 32 位或 64 位。
Boolean 布爾值。用於存儲布爾值(真/假)。
Double 雙精度浮點值。用於存儲浮點值。
Min/Max keys 將一個值與 BSON(二進制的 JSON)元素的最低值和最高值相對比。
Array 用於將數組或列表或多個值存儲爲一個鍵。
Timestamp 時間戳。記錄文檔修改或添加的具體時間。
Object 用於內嵌文檔。
Null 用於建立空值。
Symbol 符號。該數據類型基本上等同於字符串類型,但不一樣的是,它通常用於採用特殊符號類型的語言。
Date 日期時間。用 UNIX 時間格式來存儲當前日期或時間。你能夠指定本身的日期時間:建立 Date 對象,傳入年月日信息。
Object ID 對象 ID。用於建立文檔的 ID。
Binary Data 二進制數據。用於存儲二進制數據。
Code 代碼類型。用於在文檔中存儲 JavaScript 代碼。
Regular expression 正則表達式類型。用於存儲正則表達式。

ObjectId

ObjectId 相似惟一主鍵,能夠很快的去生成和排序,包含 12 bytes,含義是:

  • 前 4 個字節表示建立 unix 時間戳,格林尼治時間 UTC 時間,比北京時間晚了 8 個小時
  • 接下來的 3 個字節是機器標識碼
  • 緊接的兩個字節由進程 id 組成 PID
  • 最後三個字節是隨機數

MongoDB 建立數據庫:

use DATABASE_NAME
  • 若是數據庫不存在,則建立數據庫,不然切換到指定數據庫。

MongoDB 中默認的數據庫爲 test,若是你沒有建立新的數據庫,集合將存放在 test 數據庫中。

注意: 在 MongoDB 中,集合只有在內容插入後纔會建立! 就是說,建立集合(數據表)後要再插入一個文檔(記錄),集合纔會真正建立。

MongoDB 刪除數據庫:

db.dropDatabase()
  • 刪除當前數據庫,默認爲 test,你可使用 db 命令查看當前數據庫名。

MongoDB 建立集合:

db.createCollection(name, options)

參數說明:

  • name: 要建立的集合名稱
  • options: 可選參數, 指定有關內存大小及索引的選項

options 能夠是以下參數:

字段 類型 描述
capped 布爾 (可選)若是爲 true,則建立固定集合。固定集合是指有着固定大小的集合,當達到最大值時,它會自動覆蓋最先的文檔。當該值爲 true 時,必須指定 size 參數。
autoIndexId 布爾 (可選)如爲 true,自動在 _id 字段建立索引。默認爲 false。
size 數值 (可選)爲固定集合指定一個最大值(以字節計)。若是 capped 爲 true,也須要指定該字段。
max 數值 (可選)指定固定集合中包含文檔的最大數量。
在插入文檔時,MongoDB 首先檢查固定集合的 size 字段,而後檢查 max 字段。
在 test 數據庫中建立 runoob 集合:
> use test
switched to db test
> db.createCollection("runoob")
{ "ok" : 1 }

若是要查看已有集合,可使用 show collections 命令:

> show collections
runoob
system.indexes

MongoDB 刪除集合:

db.collection.drop()

MongoDB 插入文檔:

MongoDB 使用 insert() 或 save() 方法向集合中插入文檔,語法以下:

db.COLLECTION_NAME.insert(document)
db.col.insert({'title': '斯巴達克斯1',
        'actors': '未知',
        'type': '動做',
        '簡介': '古羅馬傳記'})

MongoDB 更新文檔:

  • MongoDB 使用 update() 和 save() 方法來更新集合中的文檔。

update() 方法用於更新已存在的文檔。
咱們在集合 col 中插入以下數據:

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

接着咱們經過 update() 方法來更新標題(title):

>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })   # 輸出信息
> db.col.find().pretty()
{
        "_id" : ObjectId("56064f89ade2f21f36b03136"),
        "title" : "MongoDB",
        "description" : "MongoDB 是一個 Nosql 數據庫",
        "url" : "http://www.runoob.com",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}
>
  • 以上語句只會修改第一條發現的文檔,若是你要修改多條相同的文檔,則須要設置 multi 參數爲 true。

save() 方法經過傳入的文檔來替換已有文檔:

db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)

MongoDB 刪除文檔:

MongoDB remove()函數是用來移除集合中的數據。
MongoDB數據更新可使用update()函數。在執行remove()函數前先執行find()命令來判斷執行的條件是否正確,這是一個比較好的習慣。

如刪除集合下所有文檔:
db.inventory.deleteMany({})

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

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

MongoDB 查詢文檔:

MongoDB 查詢文檔使用 find() 方法。

find() 方法以非結構化的方式來顯示全部文檔。

db.collection.find(query, projection)

若是你須要以易讀的方式來讀取數據,可使用 pretty() 方法:

db.col.find().pretty()

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

MongoDB 與 RDBMS Where 語句比較

操做 格式 範例 RDBMS中的相似語句
等於 { : } db.col.find({"by":"菜鳥教程"}).pretty() where by = '菜鳥教程'
小於 { :{$lt: }} db.col.find({"likes":{$lt:50}}).pretty() where likes < 50
小於或等於 { :{$lte: }} db.col.find({"likes":{$lte:50}}).pretty() where likes <= 50
大於 { :{$gt: }} db.col.find({"likes":{$gt:50}}).pretty() where likes > 50
大於或等於 { :{$gte: }} db.col.find({"likes":{$gte:50}}).pretty() where likes >= 50
不等於 { :{$ne: }} db.col.find({"likes":{$ne:50}}).pretty() where likes != 50

MongoDB 條件操做符:

條件操做符用於比較兩個表達式並從mongoDB集合中獲取數據。

MongoDB中條件操做符有:

  • (>) 大於 - $gt
  • (<) 小於 - $lt
  • (>=) 大於等於 - $gte
  • (<= ) 小於等於 - $lte

MongoDB $type 操做符:

$type操做符是基於BSON類型來檢索集合中匹配的數據類型,並返回結果。

MongoDB 中可使用的類型以下表所示:

類型 數字 備註
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined 6 已廢棄。
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255 Query with -1.
Max key 127

MongoDB Limit與Skip方法:

若是你須要在MongoDB中讀取指定數量的數據記錄,可使用MongoDB的Limit方法,limit()方法接受一個數字參數,該參數指定從MongoDB中讀取的記錄條數。

>db.COLLECTION_NAME.find().limit(NUMBER)

咱們除了可使用limit()方法來讀取指定數量的數據外,還可使用skip()方法來跳過指定數量的數據,skip方法一樣接受一個數字參數做爲跳過的記錄條數。

>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

MongoDB sort() 方法:

在 MongoDB 中使用 sort() 方法對數據進行排序,sort() 方法能夠經過參數指定排序的字段,並使用 1 和 -1 來指定排序的方式,其中 1 爲升序排列,而 -1 是用於降序排列。

>db.COLLECTION_NAME.find().sort({KEY:1})
ngjie

niu***gjie@163.com

skip(), limilt(), sort()三個放在一塊兒執行的時候,執行的順序是先 sort(), 而後是 skip(),最後是顯示的 limit()。

MongoDB 索引

索引一般可以極大的提升查詢的效率,若是沒有索引,MongoDB在讀取數據時必須掃描集合中的每一個文件並選取那些符合查詢條件的記錄。

這種掃描全集合的查詢效率是很是低的,特別在處理大量的數據時,查詢能夠要花費幾十秒甚至幾分鐘,這對網站的性能是很是致命的。

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中,索引是對數據庫表中一列或多列的值進行排序的一種結構

>db.collection.createIndex(keys, options)

在後臺建立索引:
db.values.createIndex({open: 1, close: 1}, {background: true})

一、查看集合索引
db.col.getIndexes()

二、查看集合索引大小
db.col.totalIndexSize()

三、刪除集合全部索引
db.col.dropIndexes()

四、刪除集合指定索引
db.col.dropIndex("索引名稱")

MongoDB 聚合:

MongoDB中聚合(aggregate)主要用於處理數據(諸如統計平均值,求和等),> 並返回計算後的數據結果。有點相似sql語句中的 count(*)。

aggregate() 方法

> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])

一些聚合的表達式:

表達式 描述 實例
$sum 計算總和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 計算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 獲取集合中全部文檔對應值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 獲取集合中全部文檔對應值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 在結果文檔中插入值到一個數組中。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 在結果文檔中插入值到一個數組中,但不建立副本。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根據資源文檔的排序獲取第一個文檔數據。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根據資源文檔的排序獲取最後一個文檔數據 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

管道的概念

管道在Unix和Linux中通常用於將當前命令的輸出結果做爲下一個命令的參數。

MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢後將結果傳遞給下一個管道處理。管道操做是能夠重複的。

表達式:處理輸入文檔並輸出。表達式是無狀態的,只能用於計算當前聚合管道的文檔,不能處理其它的文檔。

表達式 操做
$project: 修改輸入文檔的結構。能夠用來重命名、增長或刪除域,也能夠用於建立計算結果以及嵌套文檔。
$match: 用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操做。
$limit: 用來限制MongoDB聚合管道返回的文檔數。
$skip: 在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。
$unwind: 將文檔中的某一個數組類型字段拆分紅多條,每條包含數組中的一個值。
$group: 將集合中的文檔分組,可用於統計結果。
$sort: 將輸入文檔排序後輸出。
$geoNear: 輸出接近某一地理位置的有序文檔。

MongoDB 備份(mongodump)與恢復(mongorestore)

MongoDB數據備份

  • 在Mongodb中咱們使用mongodump命令來備份MongoDB數據。該命令能夠導出全部數據到指定目錄中。
>mongodump -h dbhost -d dbname -o dbdirectory
  • -h:
    MongDB所在服務器地址,例如:127.0.0.1,固然也能夠指定端口號:127.0.0.1:27017
  • -d:
    須要備份的數據庫實例,例如:test
  • -o:
    備份的數據存放位置,例如:c:\data\dump,固然該目錄須要提早創建,在備份完成後,系統自動在dump目錄下創建一個test目錄,這個目錄裏面存放該數據庫實例的備份數據。

MongoDB數據恢復

  • mongodb使用 mongorestore 命令來恢復備份的數據。
>mongorestore -h <hostname><:port> -d dbname <path>
  • --host <:port>, -h <:port>:
    MongoDB所在服務器地址,默認爲: localhost:27017
  • --db , -d :
    須要恢復的數據庫實例,例如:test,固然這個名稱也能夠和備份時候的不同,好比test2
  • --drop:
    恢復的時候,先刪除當前數據,而後恢復備份的數據。就是說,恢復後,備份後添加修改的數據都會被刪除,慎用哦!

  • mongorestore 最後的一個參數,設置備份數據所在位置,例如:c:\data\dump\test。 你不能同時指定 和 --dir 選項,--dir也能夠設置備份目錄。
  • --dir:
    指定備份的目錄 你不能同時指定 和 --dir 選項。
相關文章
相關標籤/搜索