雖說現在關係型數據庫還是主流,但是面對某些需求的時候,需要非關係型數據庫來補充它,學習一個主流的NoSQL數據庫還是很有必要的。MongoDB是一個功能豐富的NoSQL數據庫,本文整理了它最常用的部分形成了這篇入門教程,希望對大家有所幫助。
簡介
MongoDB是一個基於分佈式文件存儲的數據庫。由C++語言編寫,旨在爲WEB應用提供可擴展的高性能數據存儲解決方案。MongoDB是一個介於關係型數據庫和非關係型數據庫之間的產品,是非關係型數據庫當中功能最豐富,最像關係型數據庫的。
安裝
以前寫的MongoDB安裝教程是基於3.2版本的,發現有的朋友使用新版本安裝有問題,這次我們使用最新版本再來安裝一次,本文所使用的MongoDB版本爲4.2.5,總的來說,新版本的安裝更簡單了。
Windows下的安裝
- 下載MongoDB安裝包,選擇
Windows x64
版本安裝,下載地址:https://www.mongodb.com/download-center/community
- 運行MongoDB安裝包並選擇自定義安裝,設置好安裝路徑;配置MongoDB,讓MongoDB作爲服務運行,並配置好數據目錄和日誌目錄;接下來就是點下一步下一步的事情了;
Linux下的安裝
- 下載MongoDB的Docker鏡像;
docker pull mongo:4.2.5
- 使用Docker命令啓動MongoDB服務;
docker run -p 27017:27017 --name mongo \
-v /mydata/mongo/db:/data/db \
-d mongo:4.2.5
- 有時候我們需要爲MongoDB設置賬號,可以使用如下命令啓動;
docker run -p 27017:27017 --name mongo \
-v /mydata/mongo/db:/data/db \
-d mongo:4.2.5 --auth
- 然後我們需要進入容器中的MongoDB客戶端;
docker exec -it mongo mongo
- 之後在
admin
集合中創建一個賬號用於連接,這裏創建的是基於root
角色的超級管理員帳號;
use admin
db.createUser({
user: 'mongoadmin',
pwd: 'secret',
roles: [ { role: "root", db: "admin" } ] });
- 創建完成後驗證是否可以登錄;
db.auth("mongoadmin","secret")
- 整個賬號創建過程可以參考下圖。
客戶端工具
MongoDB的客戶端工具有很多,上面沒安裝的MongoDB Compass就是其中之一,另外Navicat 15版本也有MongoDB的管理功能。這裏我們使用的是一款免費的客戶端工具Robo 3T(以前叫Robomongo)。
- 首先下載客戶端工具,下載地址:https://robomongo.org/download
- 下載完成後解壓,雙擊
robo3t.exe
即可使用;
- 之後創建一個到MongoDB的連接;
- 創建連接成功以後,就可以操作MongoDB了。
相關概念
MongoDB是非關係型數據庫當中最像關係型數據庫的,所以我們通過它與關係型數據庫的對比,來了解下它的概念。
SQL概念 | MongoDB概念 | 解釋/說明 |
---|---|---|
database | database | 數據庫 |
table | collection | 數據庫表/集合 |
row | document | 數據記錄行/文檔 |
column | field | 數據字段/域 |
index | index | 索引 |
primary key | primary key | 主鍵,MongoDB自動將_id字段設置爲主鍵 |
數據庫操作
- 創建數據庫,使用
use
命令去創建數據庫,當插入第一條數據時會創建數據庫,例如創建一個test
數據庫;
> use test
switched to db test
> db.article.insert({name:"MongoDB 教程"})
WriteResult({ "nInserted" : 1 })
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
- 刪除數據庫,使用db對象中的
dropDatabase()
方法來刪除;
> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
集合操作
- 創建集合,使用db對象中的
createCollection()
方法來創建集合,例如創建一個article
集合;
> use test
switched to db test
> db.createCollection("article")
{ "ok" : 1 }
> show collections
article
- 刪除集合,使用collection對象的
drop()
方法來刪除集合,例如刪除一個article
集合;
> db.article.drop()
true
> show collections
文檔操作
上面的數據庫和集合操作是在MongoDB的客戶端中進行的,下面的文檔操作都是在Robomongo中進行的。
插入文檔
- MongoDB通過collection對象的
insert()
方法向集合中插入文檔,語法如下;
db.collection.insert(document)
- 使用collection對象的
insert()
方法來插入文檔,例如插入一個article
文檔;
db.article.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一個 Nosql 數據庫',
by: 'Andy',
url: 'https://www.mongodb.com/',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
- 使用collection對象的
find()
方法可以獲取文檔,例如獲取所有的article
文檔;
db.article.find({})
{
"_id" : ObjectId("5e9943661379a112845e4056"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一個 Nosql 數據庫",
"by" : "Andy",
"url" : "https://www.mongodb.com/",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100.0
}
更新文檔
- MongoDB通過collection對象的
update()
來更新集合中的文檔,語法如下;
db.collection.update(
<query>,
<update>,
{
multi: <boolean>
}
)
# query:修改的查詢條件,類似於SQL中的WHERE部分
# update:更新屬性的操作符,類似與SQL中的SET部分
# multi:設置爲true時會更新所有符合條件的文檔,默認爲false只更新找到的第一條
- 將title爲
MongoDB 教程
的所有文檔的title修改爲MongoDB
;
db.article.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
- 除了
update()
方法以外,save()
方法可以用來替換已有文檔,語法如下;
db.collection.save(document)
- 這次我們將ObjectId爲
5e9943661379a112845e4056
的文檔的title改爲MongoDB 教程
;
db.article.save({
"_id" : ObjectId("5e9943661379a112845e4056"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一個 Nosql 數據庫",
"by" : "Andy",
"url" : "https://www.mongodb.com/",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100.0
})
刪除文檔
- MongoDB通過collection對象的
remove()
方法來刪除集合中的文檔,語法如下;
db.collection.remove(
<query>,
{
justOne: <boolean>
}
)
# query:刪除的查詢條件,類似於SQL中的WHERE部分
# justOne:設置爲true只刪除一條記錄,默認爲false刪除所有記錄
- 刪除title爲
MongoDB 教程
的所有文檔;
db.article.remove({'title':'MongoDB 教程'})
查詢文檔
- MongoDB通過collection對象的
find()
方法來查詢文檔,語法如下;
db.collection.find(query, projection)
# query:查詢條件,類似於SQL中的WHERE部分
# projection:可選,使用投影操作符指定返回的鍵
- 查詢
article
集合中的所有文檔;
db.article.find()
/* 1 */
{
"_id" : ObjectId("5e994dcb1379a112845e4057"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一個 Nosql 數據庫",
"by" : "Andy",
"url" : "https://www.mongodb.com/",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 50.0
}
/* 2 */
{
"_id" : ObjectId("5e994df51379a112845e4058"),
"title" : "Elasticsearch 教程",
"description" : "Elasticsearch 是一個搜索引擎",
"by" : "Ruby",
"url" : "https://www.elastic.co/cn/",
"tags" : [
"elasticearch",
"database",
"NoSQL"
],
"likes" : 100.0
}
/* 3 */
{
"_id" : ObjectId("5e994e111379a112845e4059"),
"title" : "Redis 教程",
"description" : "Redis 是一個key-value數據庫",
"by" : "Andy",
"url" : "https://redis.io/",
"tags" : [
"redis",
"database",
"NoSQL"
],
"likes" : 150.0
}
- MongoDB中的條件操作符,通過與SQL語句的對比來了解下;
操作 | 格式 | SQL中的類似語句 |
---|---|---|
等於 | {<key>:<value>} |
where title = 'MongoDB 教程' |
小於 | {<key>:{$lt:<value>}} |
where likes < 50 |
小於或等於 | {<key>:{$lte:<value>}} |
where likes <= 50 |
大於 | {<key>:{$gt:<value>}} |
where likes > 50 |
大於或等於 | {<key>:{$gte:<value>}} |
where likes >= 50 |
不等於 | {<key>:{$ne:<value>}} |
where likes != 50 |
- 條件查詢,查詢title爲
MongoDB 教程
的所有文檔;
db.article.find({'title':'MongoDB 教程'})
- 條件查詢,查詢likes大於50的所有文檔;
db.article.find({'likes':{$gt:50}})
- AND條件可以通過在
find()
方法傳入多個鍵,以逗號隔開來實現,例如查詢title爲MongoDB 教程
並且by爲Andy
的所有文檔;
db.article.find({'title':'MongoDB 教程','by':'Andy'})
- OR條件可以通過使用
$or
操作符實現,例如查詢title爲Redis 教程
或MongoDB 教程
的所有文檔;
db.article.find({$or:[{"title":"Redis 教程"},{"title": "MongoDB 教程"}]})
- AND 和 OR條件的聯合使用,例如查詢likes大於50,並且title爲
Redis 教程
或者"MongoDB 教程
的所有文檔。
db.article.find({"likes": {$gt:50}, $or: [{"title": "Redis 教程"},{"title": "MongoDB 教程"}]})
其他操作
Limit與Skip操作
- 讀取指定數量的文檔,可以使用
limit()
方法,語法如下;
db.collection.find().limit(NUMBER)
- 只查詢article集合中的2條數據;
db.article.find().limit(2)
- 跳過指定數量的文檔來讀取,可以使用
skip()
方法,語法如下;
db.collection.find().limit(NUMBER).skip(NUMBER)
- 從第二條開始,查詢article集合中的2條數據;
db.article.find().limit(2).skip(1)
排序
- 在MongoDB中使用
sort()
方法對數據進行排序,sort()
方法通過參數來指定排序的字段,並使用1和-1來指定排序方式,1爲升序,-1爲降序;
db.collection.find().sort({KEY:1})
- 按article集合中文檔的likes字段降序排列;
db.article.find().sort({likes:-1})
索引
- 索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB在讀取數據時必須掃描集合中的每個文件並選取那些符合查詢條件的記錄。
- MongoDB使用
createIndex()
方法來創建索引,語法如下;
db.collection.createIndex(keys, options)
# background:建索引過程會阻塞其它數據庫操作,設置爲true表示後臺創建,默認爲false
# unique:設置爲true表示創建唯一索引
# name:指定索引名稱,如果沒有指定會自動生成
- 給title和description字段創建索引,1表示升序索引,-1表示降序索引,指定以後臺方式創建;
db.article.createIndex({"title":1,"description":-1}, {background: true})
- 查看article集合中已經創建的索引;
db.article.getIndexes()
/* 1 */
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.article"
},
{
"v" : 2,
"key" : {
"title" : 1.0,
"description" : -1.0
},
"name" : "title_1_description_-1",
"ns" : "test.article",
"background" : true
}
]
聚合
- MongoDB中的聚合使用
aggregate()
方法,類似於SQL中的group by語句,語法如下;
db.collection.aggregate(AGGREGATE_OPERATION)
- 聚合中常用操作符如下;
操作符 | 描述 |
---|---|
$sum | 計算總和 |
$avg | 計算平均值 |
$min | 計算最小值 |
$max | 計算最大值 |
- 根據by字段聚合文檔並計算文檔數量,類似與SQL中的count()函數;
db.article.aggregate([{$group : {_id : "$by", sum_count : {$sum : 1}}}])
/* 1 */
{
"_id" : "Andy",
"sum_count" : 2.0
}
/* 2 */
{
"_id" : "Ruby",
"sum_count" : 1.0
}
- 根據by字段聚合文檔並計算likes字段的平局值,類似與SQL中的avg()語句;
db.article.aggregate([{$group : {_id : "$by", avg_likes : {$avg : "$likes"}}}])
/* 1 */
{
"_id" : "Andy",
"avg_likes" : 100.0
}
/* 2 */
{
"_id" : "Ruby",
"avg_likes" : 100.0
}
正則表達式
- MongoDB使用
$regex
操作符來設置匹配字符串的正則表達式,可以用來模糊查詢,類似於SQL中的like操作; - 例如查詢title中包含
教程
的文檔;
db.article.find({title:{$regex:"教程"}})
- 不區分大小寫的模糊查詢,使用
$options
操作符;
db.article.find({title:{$regex:"elasticsearch",$options:"$i"}})