MongoDB是面向文檔的數據庫,而非關係型數據庫。它擴展了關係型數據庫的衆多有用功能,如輔助查詢、範圍查詢和排序。
它將原來的行的概念換成更加靈活的文檔模型。它沒有模式:文檔的鍵不會事先定義也不會固定不變。
MongoDB 將數據存儲爲一個文檔,數據結構由鍵值(key=>value
)對組成。MongoDB 文檔類似於 JSON 對象。字段值可以包含其他文檔,數組及文檔數組。
有些關係型數據庫的常見功能MongoDB並不具備,比如聯接(join)和複雜的多行事務。
MongoDB 的擴展性強,其採用的面向文檔的數據模型使其可以自動在多臺服務器之間分割數據。
MongoDB性能優越。它將內存管理工作交由操作系統處理;它利用查詢優化器記住執行查詢最高效的方式;它利用預分配數據文件的方式(用空間)換取性能的穩定。
MongoDB的管理理念就是儘可能的讓服務器自動配置,簡化數據庫的管理。比如如果主服務器掛掉,它會自動切換到備份服務器上,並且將備份服務器提升爲活躍服務器。
NoSQL簡介
NoSQL(NoSQL = Not Only SQL ),意即"不僅僅是SQL"。但事實上很多NoSQL數據庫都放棄了對 SQL語言的支持。
MongoDB安裝啓動和停止
安裝方法見:
- Install MongoDB Community Edition
- How to Install MongoDB on Ubuntu 16.04 - DigitalOcean
- How to Install and Configure MongoDB on Ubuntu 16.04
開啓mongod:
sudo service mongod start
進入mongo shell:
mongo
列出數據庫:
show dbs
顯示當前數據庫對象:
db
默認是 test 。
切換數據庫:
use <database>
停止 mongod:
sudo service mongod stop
或者使用下面更加穩妥的方式停止MongoDB:
# 切換到admin數據庫(讓自己具有管理員權限)
use admin
db.shutdownServer()
剛安裝的mongodb並沒有開啓用戶權限驗證;所以連接時不需要認證。
MongoDB的基本概念
在mongodb中基本的概念是文檔、集合、數據庫。
SQL術語/概念 | MongoDB術語/概念 | 解釋/說明 |
---|---|---|
database | database | 數據庫 |
table | collection | 數據庫表/集合 |
row | document | 數據記錄行/文檔 |
column | field | 數據字段/域 |
index | index | 索引 |
table joins | 表連接,MongoDB不支持 | |
primary key | primary key | 主鍵,MongoDB自動將_id字段設置爲主鍵 |
文檔
文檔類似於關係數據庫中的行。多個鍵及其關聯的值有序的放置在一起便是文檔。在JS中,文檔表示爲對象。
每個文檔都有一個特殊的鍵_id
,它在文檔所處的集合中是唯一的。
幾個重要的概念:
-
文檔中的鍵/值對是有序的。
-
文檔的鍵是字符串。一般情況鍵可以使用UTF-8字符。
- 鍵不能有
\0
空字符。它是用來表示鍵的結尾。 .
和$
只有在特定環境才能使用- 以
_
開頭的鍵是保留的
- 鍵不能有
-
MongoDB不但區分類型,也區分大小寫。下面是兩組不同的文檔:
{"foo":3} {"foo":"3"}
{"foo":3} {"Foo":3}
- MongoDB的文檔不能有重複的鍵。
集合
集合可以被看作沒有模式的表。
子集合:
組織集合的一種慣例是使用 .
字符分開的命名空間劃分的子集合。比如:
blog.post和blog.authors,這樣做只是了使組織結構更好些,也就是說blog這個集合(這裏根本就不需要存在)及其子集合沒有任何關係。
數據庫
一個MongoDB實例可以承載多個數據庫。不同的數據庫存放在不同的文件中
要記住數據庫名最終會變成文件系統裏的文件,所以數據庫名必須遵守一些約定。
保留的特殊數據庫:
- admin:從權限角度上看,這是 root 數據庫。
- local:這個數據庫永遠不會被複制,可以用來存儲限於本地服務器的任意集合。
- config:但Mongo用於分片設置時,config數據庫在內部使用,用於保存分片的相關信息。
命名空間:把數據庫的名字放到集合名前面,得到的集合的完全限定名稱。
數據類型
MongoDB的文檔類似於JSON,在概念上和JavaScript中的對象神似。MongoDB在保留JSON基本的鍵/值對特性的基礎上,添加了其它一些數據類型。在不同的編程語言下這些類型表示有些許差異。
-
null:
-
布爾:
-
32位整數:
-
64位整數:
-
64位浮點數:
-
字符串
-
符號
-
對象id:ObjectId()。(文檔必須有一個"_id"鍵;這個鍵的值可以是任意類型,默認是ObjectId對象。)
-
日期: new Date()
-
正則表達式:採用JavaScript的正則表達式語法
-
代碼: 文檔中還可以包含JavaScript代碼
{"x" : function(){/* */}}
-
二進制數據:
-
最大值
-
最小值
-
undefined
-
數組:值的集合或者列表可以表示成數組
{"x" : ["a","b","c"]}
- 內嵌文檔:
文檔可以包含別的文檔,也可以作爲值嵌入到父文檔中{"x" : {"foo" : "bar"}}
數據庫管理
默認數據目錄 /data/db
,並使用27017端口。它還會啓動一個非常基本的http服務器,監聽數字比主端口號高 1000 的端口,比如 28017 端口。
MongoDB Shell
MongoDB自帶一個 JavaScript shell,可以從命令行與MongoDB實例交互。它也是一個完備的JS解釋器,可以運行任何JS程序。
開啓的時候,shell會連接到MongoDB服務器的 test 數據庫,並將這個數據庫連接賦值給全局變量 db 。這個變量是通過 shell 訪問 MongoDB的主要入口點。
shell還提供了一些語法糖,比如選擇數據庫的 usr dbName
,執行該操作後 db 變量的值也會發生改變。
# 運行 mongo 啓動 shell
mongo
# 列出數據庫
show dbs
# 切換數據庫,如果該數據庫不存在則創建該數據庫
use imooc
# 刪除數據庫
db.dropDatabase()
增刪改查
插入文檔
對目標集使用insert方法,插入一個文檔:
db.foo.insert({"bar":"baz"})
該操作會自動增加一個 "_id" 鍵(要是原來沒有)再保存到數據庫
批量插入:
批量插入能傳遞一個由文檔構成的數組給數據庫。
插入數據時:數據庫只會驗證是否包含"_id"鍵,然後就簡單的將文檔原樣的存入數據庫。
MongoDB在插入時並不執行代碼,所以這塊沒有注入式***的可能。
刪除文檔
刪除users集合中的所有文檔,但不刪除集合本身:
db.users.remove()
remove函數可以接受一個查詢文檔作爲可選參數。這樣只有符合條件的文檔才能被刪除。
示例:所有"optout"爲true的將被刪除:
db.mailing.list.remove({"opt-out" : true})
直接刪除集合:
db.drop_collection("bar")
更新文檔
使用update方法。該方法由兩個參數,一個是查詢文檔,用來找出要更新的文檔;另一個是修改器(modifier)文檔,描述對找到的文檔做哪些更改。
更新操作是原子的:若是兩個更新同時發生,先到達服務器的先執行,接着執行另外一個。
更新修改器:是一種特殊的鍵,用來指定複雜的更新操作。
"$set"
修改器
"$set"
修改器用來指定一個鍵的值。如果這個鍵不存在,則創建它。
示例:添加喜歡的書籍到某用戶信息
db.users.update(
{"_id":ObjectId("4fksdftudkf4964trub")}, //查詢文檔
{"$set":{"favorite book" : "war and peace"}} //修改器文檔
)
對應的可以使用 "$unset"
將鍵完全刪除。
"$inc"
修改器
"$inc"
修改器:用來增加已有的值,如果鍵不存在則創建一個鍵。
它只能用於整數、長整數活浮點數。
db.games.update({"game":"pinball","user":"joe"}, //查詢文檔
{"$inc":{"score":50}}) //修改器文檔
上面示例:滿足條件的玩家加50分,如果分數鍵(score)不存在則先創建該鍵。這裏增量爲50。
"$push"
修改器
用於數組。"$push"
修改器會向已有的數組末尾加入一個元素,若是該鍵不存在則會創建一個新的數組。
注意:這裏是指集合中的某個鍵的值爲數組,現在要向這個數組中添加元素。
比如 blog.post集合如下:
{
id : ObjectId("4dkfs53rt9rufhvjr0fv"),
title : "A blog post",
content : "...",
comments : [
{
name : "joe",
email : "[email protected]",
content : "nice post"
}
]
}
當我們想向comments這個數組中添加一個元素,就可以使用 $push
。
查詢文檔
使用 find 或者 findOne 函數和查詢文檔對數據庫執行查詢。
查詢簡單的類型,只要指定想要查找的值就好了。示例,查找所有"age"的值爲27的文檔:
db.users.find({"age":27})
查詢條件:
相關操作符 | 描述 |
---|---|
$lt |
< |
$lte |
<= |
$gt |
> |
$gte |
>= |
$ne |
不等於 |
$in |
用來查詢一個鍵的多個值 |
$nin |
返回與數組中所有條件都不匹配的文檔 |
$or |
用來完成多個鍵值的任意給定值 |
$not |
是元語句,可以用在任何其他條件之上 |
查詢在 18 ~ 30歲的用戶:
db.users.find({"age": {"$gte": 18, "$lte": 30} })
使用$in
對單個鍵做OR查詢
db.raffle.find({"ticket_no" : {"$in" : [725,542,390]}})
使用$or
可以對多個鍵做OR查詢。示例,找到 ticket_no 爲 725或者winner爲true的文檔:
db.raffle.find({"$or" : [{"ticket_no" : 725}, {"winner", true}]})
查詢數組
例如:數組是一個水果清單
db.food.insert({"fruit" : ["apple","banana","peach"]})
下面的查詢會匹配該文檔:
db.food.find({"fruit","banana"})
$all
:通過多個元素來匹配數組。
找到既有 apple 又有 banana 的文檔:
db.food.find({fruit: {$all : ["apple","banana"]}})
$size
用於查詢指定長度的數組。
db.food.find({fruit: {$size : 3}})
查詢內嵌文檔
如果允許通常只針對內嵌文檔的特定鍵值進行查詢纔是比較好的做法,這樣即便數據模式改變,也不會有太大問題。
我們可以使用"點表示法"查詢內嵌的鍵:
db.people.find({"name.first" : "Joe", "name.last" : "Schome"})
"$where"
查詢
"$where"
子句可以執行任意JavaScipt作爲查詢的一部分。由了它的補充,使得查詢能做任何事情。
最典型的應用就算比較文檔中的兩個鍵的值是否相等。
db.foo.find({"$where" : "function(){return this.x + this.y == 10; }" })
注意:"$where"
查詢在速度上要比其他常規查詢慢很多。
遊標
數據庫使用 遊標 來返回find的執行結果。find返回的對象就是一個遊標。
遊標的方法:
- next():獲取下一個結果
- hasNext():檢查是否有後續結果存在
- limit():限制結果數量
- skip():忽略一定數量的結果
- sort():對結果排序
幾乎所有的遊標的方法返回值也是遊標,這樣就可以組成方法鏈。
管理MongoDB
從命令行啓動MongoDB
直接執行 mongod
,即可簡單的啓動服務器。該命令還有很多可配置的啓動選項:
選項 | 描述 |
---|---|
--help | 查看所有選項 |
--dbpath | 指定數據目錄。默認值是/data/db |
--port | 指定服務器監聽的端口號 |
--fork | 以守護進程的方式運行MongoDB,創建服務器進程 |
--logpath | 指定日誌輸出路徑,而不是輸出到命令行 |
--config | 指定配置文件。配置文件中 # 是註釋符號;語法形式是"選項-值"的形似。 |
每個mongod進程都需要獨立的數據目錄。當mongod啓動時,會在數據目錄中創建mongod.lock文件,該文件用於防止其他mongod進程使用該數據目錄。並且要給它們指定不同的端口號。
停止MongoDB
這裏只介紹一個穩妥的停止數據庫的方法:使用shutdown命令,{"shutdown" : 1}
,這是管理命令,要在 admin 數據庫下使用。 MongoDB shell 提供了輔助函數,來簡化這一過程:
> use admin
switched to db admin
> db.shutdownServer();
server should be down...
學習資料
《MongoDB權威指南》
MongoDB 教程 - 菜鳥教程
官方手冊:The MongoDB Manual
MongoDB中文社區
MongoDB中文網
Mongodb最佳實踐-麥子學院
MongoDB基礎教程-慕課網課程
圖形工具: Robo 3T - formerly Robomongo — native MongoDB management tool (Admin UI)
來自於我的簡書:faner - 簡書