1.MongoDB簡介
MongoDB是一個開源的,基於分佈式的,面向文檔存儲的非關係型
數據庫,是非關係型數據庫中比較像關係型數據庫的。MongoDB由C++編寫,名字來源於humongous
這個單詞,旨在於處理大量數據。
MongoDB 將數據存儲爲一個文檔,數據結構由鍵值(key-value)對組成。MongoDB 文檔類似於JSON
對象。字段值可以包含其他文檔,數組及文檔數組。
MongoDB的特點:
- 面向集合存儲,易存儲對象類型的數據。
- 模式自由。集合中沒有行和列的概念,每個文檔可以有不同的key,key的值不要求一致的數據類型。
- 支持動態查詢。支持豐富的查詢表達式,查詢指令可以使用JSON形式表達式。
- 支持索引。
- 支持查詢。
- 支持複製和故障恢復。
- 使用高效的二進制數據存儲,包括大型對象(如視頻等)。
- 自動處理碎片,以支持雲計算層次的擴展性。
- 支持C/C++,PHP,Ruby,Python,Java等多種語言。
- 文件存儲格式爲
BSON
(一種JSON的擴展,JSON的二進制)
MongoDB應用場景:
- 京東,中國著名電商,使用MongoDB存儲商品信息,支持比價和關注功能。
- 趕集網,中國著名分類信息網站,使用MongoDB記錄pv瀏覽計數。
- 奇虎360,著名病毒軟件防護和移動應用平臺,使用MongoDB支撐的HULK平臺每天接受200億次的查詢。
- 百度雲,使用MongoDB管理百度雲盤中500億條關於文件源信息的記錄。
2.MongoDB的基本概念
在mongodb中基本的概念是文檔、集合、數據庫。
SQL術語 | MongoDB術語 | 說明 |
---|---|---|
database | database | 數據庫 |
table | collection | 數據庫表、集合 |
row | document | 數據記錄行、文檔 |
column | field | 數據字段、域 |
index | index | 索引 |
table joins | 嵌入文檔 | 表連接,MongoDB不支持,可通過內嵌和包含關聯ID實現 |
primary key | primary key | 主鍵,MongoDB自動將_id字段設置爲主鍵 |
- 文檔
文檔是一個鍵值(key-value)對(即BSON)。MongoDB的文檔不需要設置相同的字段,並且相同的字段不需要相同的數據類型,這與關係型數據庫有很大的區別,也是 MongoDB 非常突出的特點。 - 集合
文檔組,類似於關係數據庫中的表格。集合可以插入不同格式和類型的數據,但通常情況下我們插入集合的數據都會有一定的關聯性。當第一個文檔插入時,集合就會被創建。
比如,我們可以將以下不同數據結構的文檔插入到集合中:
{"site":"www.baidu.com"}
{"site":"www.google.com","name":"Google"}
- 分佈式數據庫系統
由分佈於多個計算機結點上的若干個數據庫系統組成,它提供有效的存取手段來操縱這些結點上的子數據庫。分佈式數據庫在使用上可視爲一個完整的數據庫,而實際上它是分佈在地理分散的各個結點上。 ObjectId
數據類型
ObjectId
類似唯一主鍵,可以很快的去生成和排序,包含12 bytes
。
3.MongoDB的基本操作
3.1 創建刪除數據庫
創建/切換:
use DATABASE_NAME
顯示所有數據庫名:
show dbs
查看當前數據庫的名稱:
db
查看所有的collection,下面兩條指令都可以:
show collections
show tables
刪除當前的數據庫
db.dropDatabase()
MongoDB 中默認的數據庫爲 test,如果你沒有創建新的數據庫,集合將存放在 test 數據庫中。
3.2 增加文檔
MongoDB 使用 insert() 或 save() 方法向集合中插入文檔:
db.COLLECTION_NAME.insert(document)
例如:
db.test.insert({title: 'mongo test',
description: 'MongoDB是Nosql數據庫',
url: 'http://mongodb.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 200
})
> db.test.insert({title: 'mongo test',
... description: 'MongoDB是Nosql數據庫',
... url: 'http://mongodb.com',
... tags: ['mongodb', 'database', 'NoSQL'],
... likes: 200
... })
WriteResult({ "nInserted" : 1 })
> db.test.find()
{ "_id" : ObjectId("5e393d940cd9aa50e890348c"), "title" : "mongo test", "description" : "MongoDB是Nosql數據庫", "url" : "http://mongodb.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 200 }
insert() 和 save() 方法區別:
- save函數實際就是根據參數條件,調用了insert或update函數。如果想插入的數據對象存在,insert函數會報錯,而save函數是改變原來的對象。如果想插入的對象不存在,那麼它們執行相同的插入操作。
- insert可以一次性插入一個列表,而不用遍歷,效率高, save則需要遍歷列表,一個個插入。
- 如果不指定
_id
字段save()
方法類似於insert()
方法。如果指定_id
字段,則會更新該_id
的數據。
3.2版本後還有以下幾種語法可用於插入文檔:
db.collection.insertOne()
:向指定集合中插入一條文檔數據db.collection.insertMany()
:向指定集合中插入多條文檔數據
> var document = db.test.insertOne({"a": 3})
> document
{
"acknowledged" : true,
"insertedId" : ObjectId("5e393e640cd9aa50e890348d")
}
> db.test.find()
{ "_id" : ObjectId("5e393d940cd9aa50e890348c"), "title" : "mongo test", "description" : "MongoDB是Nosql數據庫", "url" : "http://mongodb.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 200 }
{ "_id" : ObjectId("5e393e640cd9aa50e890348d"), "a" : 3 }
> var res = db.test.insertMany([{"b": 3}, {'c': 4}])
> res
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5e393e980cd9aa50e890348e"),
ObjectId("5e393e980cd9aa50e890348f")
]
}
> db.test.find()
{ "_id" : ObjectId("5e393d940cd9aa50e890348c"), "title" : "mongo test", "description" : "MongoDB是Nosql數據庫", "url" : "http://mongodb.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 200 }
{ "_id" : ObjectId("5e393e640cd9aa50e890348d"), "a" : 3 }
{ "_id" : ObjectId("5e393e980cd9aa50e890348e"), "b" : 3 }
{ "_id" : ObjectId("5e393e980cd9aa50e890348f"), "c" : 4 }
>
3.3 查詢文檔
查詢格式如下:
db.COLLECTION_NAME.find({COND},{FIELDS})
find() 方法以非結構化的方式來顯示所有文檔。
如果你需要以易讀的方式來讀取數據,可以使用 pretty() 方法,語法格式如下:
db.test.find().pretty()
> db.test.find().pretty()
{
"_id" : ObjectId("5e393d940cd9aa50e890348c"),
"title" : "mongo test",
"description" : "MongoDB是Nosql數據庫",
"url" : "http://mongodb.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 200
}
{ "_id" : ObjectId("5e393e640cd9aa50e890348d"), "a" : 3 }
{ "_id" : ObjectId("5e393e980cd9aa50e890348e"), "b" : 3 }
{ "_id" : ObjectId("5e393e980cd9aa50e890348f"), "c" : 4 }
3.4 修改文檔
更新數據格式如下:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
參數說明:
- query:update的查詢條件,類似sql update查詢內where後面的。
- update:update的對象和一些更新的操作符(如inc…)等,也可以理解爲sql update查詢內set後面的
- upsert :可選,這個參數的意思是,如果不存在update的記錄,是否插入objNew,true爲插入,默認是false,不插入。
- multi :可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數爲true, 就把按條件查出來多條記錄全部更新。
- writeConcern :可選,拋出異常的級別。
實例:
我們在集合col
中插入如下數據:
> db.col.insert({
... title: 'MongoDB 教程',
... description: 'MongoDB 是一個 Nosql 數據庫',
... url: 'http://www.baidu.com',
... tags: ['mongodb', 'database', 'NoSQL'],
... likes: 100
... })
WriteResult({ "nInserted" : 1 })
接着我們通過 update()
方法來更新標題(title
):
> db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 輸出信息
可以看到標題(title
)由原來的 "MongoDB 教程"
更新爲了 "MongoDB"
。以上語句只會修改第一條發現的文檔,如果你要修改多條相同的文檔,則需要設置 multi
參數爲 true
。
> db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
3.5 刪除文檔
執行remove()函數前先執行find()命令來判斷執行的條件是否正確
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
參數說明:
- query :(可選)刪除的文檔的條件。
- justOne : (可選)如果設爲 true 或 1,則只刪除一個文檔.默認是true
- writeConcern :(可選)拋出異常的級別。
例如:
> db.col.find()
{ "_id" : ObjectId("5e396c6b0cd9aa50e8903491"), "title" : "MongoDB", "description" : "MongoDB 是一個 Nosql 數據庫", "url" : "http://www.baidu.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
> db.col.remove({ "_id" : ObjectId("5e396c6b0cd9aa50e8903491")})
WriteResult({ "nRemoved" : 1 })