算是學習下來精煉的筆記,希望對大家有幫助,如果有問題歡迎大家指正,
0.概述
MongoDB 是由C++語言撰寫的,是一個基于分布式檔案存盤的開源資料庫系統,
在高負載的情況下,添加更多的節點,可以保證服務器性能,
MongoDB 旨在為WEB應用提供可擴展的高性能資料存盤解決方案,
MongoDB 將資料存盤為一個檔案,資料結構由鍵值(key=>value)對組成,MongoDB 檔案類似于 JSON 物件,欄位值可以包含其他檔案,陣列及檔案陣列,
下面是與sql概念的對比,能夠幫助我們更好的理解mongodb,
| SQL術語/概念 | MongoDB術語/概念 | 解釋/說明 |
|---|---|---|
| database | database | 資料庫 |
| table | collection | 資料庫表/集合 |
| row | document | 資料記錄行/檔案 |
| column | field | 資料欄位/域 |
| index | index | 索引 |
| table joins | 表連接,MongoDB不支持 | |
| primary key | primary key | 主鍵,MongoDB自動將_id欄位設定為主鍵 |
總結下來,傳統的關系型資料庫的內容結構是
- 資料庫
- 表
- 行
- 欄位
Mongodb與之對應的就是
- 資料庫
- 集合
- 檔案
- 域
1.brew安裝
不推薦用brew,因為現在mongodb閉源了,brew里已經搜索不到mongodb,不過還是可以用brew安裝的,這篇就不寫了,
2.官網下載
直接去官網下載一個zip,解壓完放到usr/local/里(control+shift+,可以顯示隱藏檔案夾),改名為mongodb,
然后添加一個環境變數就可以用了
$ export PATH=/usr/local/mongodb/bin:$PATH
這樣就添加好了,反正就是現在可以用了,
可以用mongo來測驗是否安裝好了,如果都弄好了應該會彈出版本,
3.創建data/db檔案夾
接下來就是新建data/db然后運行mongodb的步驟了,
不過mac os catalina現在有問題,跟目錄不讓寫東西了,所以要曲線救國,根據mongodb給的最新的解決辦法就是在/Users/(你的用戶名)/data/db/里當目錄了
最后帶上--dbpath= ,如果不添加會默認到/data/db里
sudo mongod --dbpath=/Users/Wangzirui/data/db
如果不是卡特琳娜那好說,
sudo mkdir -p /data/db 然后 sudo mongod 就完事了,
更改catelina限制之后(關閉sip),可以直接用 sudo mount -uw / 更改跟目錄權限,就可以直接sudo mongod就完事了,
然后另一個終端進入/usr/loacl/mongodb/bin/
然后./mongo就啟動了mongo的客戶端
或者直接mongo也可以,
4.開啟服務創建客戶端
啟動服務:
sudo mount -uw /
sudo mongod
啟動客戶端:
mongo
5.命令
5.1 db操作
-
顯示資料庫
- show dbs
-
切換資料庫,沒有就新建一個
- use admin
-
顯示你在哪個資料庫里
- Db
-
洗掉當前你use的那個資料庫
- db.dropDatebase()
-
新建資料庫
- use 資料庫名字
- 建完了show dbs不會立刻顯示,因為剛才新建的資料庫里面沒有資料,所以顯示不出來,
5.2 collection操作
-
顯示這個資料庫中有什么集合
- show collections
-
新建集合,在use 一個資料庫的情況下
- db.createCollections(name,options)
- 然后show dbs現在可以看到use的資料庫了
-
洗掉集合 ,在現在這個Use的資料庫的情況下
- db.你想要的collectionname.drop()
- 然后就刪掉了
5.3 document操作
collectionname代指相對應的collcetion名字(mysql里叫表,Mongodb里叫collection,都是一個資料庫里的一種結構) 現在操作的不是表也不是集合,而是集合里的一個資料結構叫做document,檔案,檔案相當于mysql里的一個記錄行,
-
往collection里加資料,直接新建document
- db.collectionname.insert({"name":"wangzirui"})
- 增加多條要在insert的多個物件的外面加一個中括號,表示這是一個物件陣列,
- db.collectionname.insert([{name:"wangzirui"},{name:"laoli"}])
-
查看collection里的資料
- db.collectionname.find()
-
Save,在_id一樣的情況下可以不報錯,然后直接覆寫掉剛才重復Id的內容,
- db.collectionsname.save({_id:1001,name:"laowang",age:22})
-
更新document資料
- db.collectionname.update({當前資料},{替換資料},{配置項})
- db.collectionname.update({name:"laotie"},{name:"ergou"})
- 這樣會洗掉其他內容,只存在一個name :ergou 所以要加$set保留其他的引數
- db.collectionname.update({name:"laotie"},{$set:{name:"ergou"}})
- 配置項里加{Multi:true}加一個這個的話可以讓多個name:"laotie"一起改
- db.collectionname.update({name:"laotie"},{$set:{name:"ergou"}},{multi:true})
-
洗掉document內容,如果不加第二個引數,默認是把集合里的符合第一條的都刪掉,
- Db.collectionname.remove({name:"laotie"},{justOne:true})
5.4 document 查詢
經過上面的講述,能了解到一點,基于database來查詢collections里的資料都是通過db.collcetion_name.方法 來進行操作的,同理,對document的查詢,我們之前也在查看collection時用過,他就是find()方法,
find里面可以加引數,不加的話就是現實collection里所有的document,
-
find()方法里可以加條件,例如db.collectionname.find({age:18})
- 如果一行一行的話不好看,可以再db.collectionname.find({age:18})后面加.pretty()
-
比較運算子
- less than 小于 $lt db.collection_name.find(age:{$lt:18})
- less than equal 小于等于 $lte
- Geater than 大于 $gt
- $gte 大于等于
- $ne 不等于
-
取范圍內的 $in
- $in:[10,20,30]
- db.collection_name.find({age:{$in:[10,20,30]}})
-
并操作
- db.collection_name.find(age:18,name:"laotie")
-
或操作
- db.collection_name.find({$or:[{age:18},{name:"laotie"}]}
-
正則
- db.collection_name.find({age:/1/})或者db.collection_name.find({age:$regex:"1"})
-
限制和跳過,一般用于分頁
- limit(2)
- skip(2)
-
投影
- 比如說find({這里放具體引數},{這里放投影})
- db.collection_name.find({age:{$lt:18}},{_id:0,age:1}) 這樣只會顯示每個物件里面只有一個age選項了
- 注意,如果投影里不加_id的選項的話 ,默認是自動顯示的,只能給_id設定 0,如果別的欄位不想讓他顯示直接不在里面加,其他的想要顯示的話直接把屬性加進去就行了,
-
通過Js函式來篩選資料
-
$where:
-
db.collection_name.find({$where:function(){
Return age>10}})
-
-
根據某個欄位排序
- sort
- db.collection_name.find().sort({age:1}) 如果降序的話要帶-1
-
計數
-
count()
-
直接在查詢出來的后面加上就可以顯示了
-
db.collection_name.find({$where:function(){
Return age>10}}).count()
-
-
去重
- db.student.distinct("name",{"age" : 18})
- 這樣可以直接把name一樣還有age為18的都給去重
6.備份和恢復
6.1備份
直接在終端輸入,不要在mongodb的客戶端輸入
mongodump -h hostname -d dbname -o dbdirectory
-h 服務器地址,可以指定埠號,本機可以不填
-d 具體Mongodb下哪個資料庫
-o 你想保存到本地的什么地方
例如本機 下在termainal直接輸入 mongodump -d laotie -o wenjianjia
然后就把 laotie這個資料庫保存到Users/wangzirui/wenjianjia這個檔案夾里了
6.2恢復
同樣直接在終端輸入
Mongorestore -h hostname -d dbname --dir
-h 服務器地址,可以指定埠號,本機可以不填
-d 你想讓這個資料庫叫什么,不一定是原名
-Dir 這個備份檔案在哪里
7.聚合
aggregate,就是一個管道,類似中間件或者是函式的鏈式呼叫,最侄訓出想要的資料,
7.1group
首先放一個student集合的資料,聚合所有的操作都是按照這些資料來的,
> db.student.find()
{ "_id" : ObjectId("5e003b92f197cb08dc74a311"), "name" : "duanyuxin", "age" : 21, "sex" : "male" }
{ "_id" : ObjectId("5e003b92f197cb08dc74a312"), "name" : "baiyu", "age" : 20, "sex" : "male" }
{ "_id" : ObjectId("5e003f66f197cb08dc74a313"), "name" : "wangzirui", "age" : 22, "sex" : "male" }
{ "_id" : ObjectId("5e003f8ff197cb08dc74a314"), "name" : "zhuhuan", "age" : 22, "sex" : "female" }
{ "_id" : ObjectId("5e003f8ff197cb08dc74a315"), "name" : "caoyajing", "age" : 12, "sex" : "female" }
先放例子:
> db.student.aggregate({
$group:{_id:"$sex",avg_age:{$avg:"$age"}}
})
{ "_id" : "male", "avg_age" : 21 }
{ "_id" : "female", "avg_age" : 17 }
在$group的物件里,前面開頭的域(欄位)代表下面將要輸出的域的值, 后面的$sex表示的是我拿什么東西當做group分組的鍵值,如果我針對不同的age分組,那么我將會得到
> db.student.aggregate({
$group:{_id:"$age"}
})
{ "_id" : "12"}
{ "_id" : "20"}
{ "_id" : "21"}
{ "_id" : "22"}
的結果,
接著說avg_age,這個域是我們自己定義的,(可能是先入為主,我總覺得說欄位更為適應,大家也更容易理解),叫什么都行,但是后面$avg:"$age"的意思就是,首先前面$avg就是取平均值,取得就是你后面$age的平均值,然后輸出的時候就列印"avg_age:前面符合id分類的檔案的age平均值"
如果想計算整個檔案的某些值,僅需要把_id:null然就可以不分組,直接用整個檔案來算,
> db.student.aggregate({
$group:{_id:null,avg_age:{$avg:"$age"}}
})
{ "_id" : null, "avg_age" : 19.4 }
$sum:
另外講一個$sum的用法,先看怎么用,
> db.student.aggregate({
$group:{_id:null,count:{$sum:1},avg_age:{$avg:"$age"}}
})
{ "_id" : null, "count" : 5, "avg_age" : 19.4 }
在剛才的基礎上加了一個$sum:1里 $sum顧名思義是求和用的,后面是求和的倍數,如果你設成2的話結果就乘2變成10.一般用來計數的話普遍還是設定成1的,
利用$group去重:
$group不止可以添加一個分組條件,也可以添加多個分組條件,如果把每個條件都對應檔案的域,那么就相當于去重操作,
> db.student.aggregate({
$group:{_id:{name:"$name",sex:"$sex",age:"$age"}}
})
然后接下來用別的通道來進行下一步的操作就可以了,但是接下來的操作要用到的屬性就是$_id.name 類似的,因為我們去重時把屬性都給了叫_id的域,
7.2$project
重構輸出結構,也就是在aggregete的通道特性,然在最后調整你想要的輸出結構,大體上和投影類似,
放栗子:
> db.student.aggregate(
{
$group:{_id:null,count:{$sum:1},avg_age:{$avg:"$age"}}
},
{
$project:{sex:"$_id",count:"$count",avg_age:"$avg_age"}
}
)
{ "_id" : null, "sex" : null, "count" : 5, "avg_age" : 19.4 }
同理,可以用1 或者0代替,具體不舉例子了,沒什么大用,
7.4 $match
聽名字就知道是過濾用的,雖然find同樣可以過濾,但是不能將find出來的結果傳給下一個管道,
比如說你想呀知道年齡大于20的男生和女生分別有幾個人
可以按照下面的方式操作
db.student.aggregate(
{$match:{age:{$gt:19}}},
{$group:{_id:"$sex",count:{$sum:1}}},
{$project:{_id:0,sex:"$_id",count:1}}
)
{ "count" : 3, "sex" : "male" }
{ "count" : 1, "sex" : "female" }
大體就是這樣,里面填的東西和find里是差不多的,
7.5 $sort
用法跟普通的用法一致,直接放栗子:
db.student.aggregate(
{$group:{_id:"$sex",count:{$sum:1}}},
{$sort:{age:1}}
)
{ "_id" : "female", "count" : 2 }
{ "_id" : "male", "count" : 3 }
如果前面的其他方法都看懂了,這個應該不成問題,就不解釋了,
7.6 $limit,skip
同樣跟前面很像,直接放例子:
db.student.aggregate(
{$skip:2},{$limit:2}
)
{ "_id" : ObjectId("5e003f66f197cb08dc74a313"), "name" : "wangzirui", "age" : 22, "sex" : "male" }
{ "_id" : ObjectId("5e003f8ff197cb08dc74a314"), "name" : "zhuhuan", "age" : 22, "sex" : "female" }
不解釋了,
8.創建索引
for(i=0;i<100000;i++){db.test.insert({name:'test'+i,age:i})}
在資料量特別龐大的時候,尋找資料就會變得慢一點,
所以要針對性的給集合建立索引
db.test.ensureIndex({name:1})
然后這個集合就有兩個索引了,之前那個索引叫_id,現在添加了一個域name也作為索引,
關于索引的幾個操作:
- 創建唯一索引
- db.test.ensureIndex({name:1},{uniqe:true})
- 建立聯合索引
- db.test.ensureIndex({name:1},{age:1})
- 查看當前集合的索引
- db.test.getIndexes()
- 洗掉索引
- db.t1.dropIndex("索引名")
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/26226.html
標籤:NoSQL
上一篇:MongoDB(八):索引
下一篇:Hbase架構剖析
