分佈式專題-分佈式緩存技術之MongoDB02-常用命令及配置

前言

前面的章節,關於分佈式緩存技術,我們分析了《分佈式緩存技術之Redis的使用以及原理》、從這一節開始,我們繼續來說說MongoDB。

關於MongoDB,一共五小節內容,分別是:

安裝 MongoDB 數據庫(Windows 和 Linux 環境)

Windows 環境

打開官網:MongoDB 官網下載地址 選擇 Community Server 4.0.1 的版本。

在這裏插入圖片描述
安裝與啓動

在D 盤創建安裝目錄,D:\MongoDB,將解壓後的文件拷入新建的文件。

在D 盤創建一個目錄,D:\MongoDB\Server\4.0\Data,用於存放 MongoDB 的數據。

執行安裝,使用命令行,進入 MongDB 的安裝目錄,執行安裝命令,並指明存放 MongoDB 的路徑。

在這裏插入圖片描述
安裝完成後配置環境變量在這裏插入圖片描述

啓動數據庫
在這裏插入圖片描述
注意,如果這是你的目錄中有空格,會報 Invalid command 錯誤,將 dbpath 後面的值加上雙引號即

可mongod.exe -dbpath=”D:\MongoDB\Server\4.0\data”。

最後一行顯示我們的 MongoDB 已經連接到 27017,它是默認的數據庫的端口;它建立完數據庫之後,會在我們的 MongoDbData 文件夾下,生成一些文件夾和文件:在 journal 文件夾中會存儲相應的數據文件,NoSQL 的 MongoDB,它以文件的形式,也就是說被二進制碼轉換過的 json 形式來存儲所有的數據模型。

啓動 MongoDB 數據庫,也可以根據自己配置 mongodb.bat 文件,在 D:\MongoDB\Server\4.0\bin 中創建一個 mongodb.bat 文件,然後我們來編寫這個可執行文件如下:

mongod --dbpath=D:\MongoDB\Server\4.0\data 運行 mongodb.bat 文件,MongoDB 便啓動成功!

在這裏插入圖片描述

Linux 環境

  1. 解壓tgz包(我使用的是Centos6.7版本)
    在這裏插入圖片描述

  2. cd到安裝目錄,並觀察啓動命令 >…<

在這裏插入圖片描述
請注意:

mongo命令: 客戶端
mongos命令: 路由器
mongod命令: 數據存儲

  1. 配置環境變量

在任意地方編輯環境變量,注意,我這裏使用的是centos6.7版本,讀者可根據不同的版本選擇相應的配置文件:

vi /etc/profile

在這裏插入圖片描述

重新加載配置文件:

source etc/profile

  1. 測試安裝
    直接啓動,提示找不到存放數據的文件夾
    在這裏插入圖片描述
    我們就在當前mongodb目錄下創建data與log文件夾
    在這裏插入圖片描述

再次啓動:

mongod
設置數據存儲路徑:–dbpath=/data/program/mongodb-linux-x86_64-4.0.18/data
設置日誌存儲路徑:–logpath=/data/program/mongodb-linux-x86_64-4.0.18/log
設置後臺啓動: -fork
設置外聯(第三方連接DB): --bind_ip=0.0.0.0

在這裏插入圖片描述
結果成功:
在這裏插入圖片描述
使用mongo進入mongo命令行
在這裏插入圖片描述
這樣就沒有問題啦·~

安裝 RoboMongo 客戶端

使用遠程連接時,記得關閉防火牆:
在這裏插入圖片描述
然後使用圖形化界面連接一下:

在這裏插入圖片描述

MongoDB 基本操作

MongoDB 常用命令

  1. 創建數據庫
use testdb

命令行效果:
在這裏插入圖片描述
客戶端效果:
在這裏插入圖片描述
以下執行經過測試沒有問題,讀者可以自行測試相關命令~

  1. 創建集合
db.t_member.insert({name:"zhaomin",age:23})
  1. 查詢
db.t_member.find()
db.t_member.findOne()
  1. 修改
#不會影響其他屬性列 ,主鍵衝突會報錯
db.t_member.update({name:"zhaomin"},{$set:{age:18}})

#第三個參數爲 true 則執行 insertOrUpdate 操作,查詢出則更新,沒查出則插入,或者
db.t_member.update({name:"zhaomin"},{$set:{age:18}},true)
  1. 刪除
#刪除滿足條件的第一條 只刪除數據 不刪除索引
db.t_member.remove({age:1})

#刪除集合
db.t_member.drop();

#刪除數據庫
db.dropDatabase();
  1. 查看集合
show collections
  1. 查看數據庫
show dbs
  1. 插入數據
db.t_member.insert() #不允許鍵值重複

db.t_member.save() #若鍵值重複,可改爲插入操作
  1. 批量更新
db.t_member.update({name:"zhaomin"},{$set:{name:"zhanmin11"}},false,t rue);

批量操作需要和選擇器同時使用,第一個 false 表示不執行 insertOrUpdate 操作,第二個 true 表示執行批量

  1. 更新器使用$set : 指定一個鍵值對,若存在就進行修改,不存在則添加 $inc :只使用於數字類型,可以爲指定鍵值對的數字類型進行加減操作:
db.t_member.update({name:"zhangsan"},{$inc:{age:2}})

執行結果是名字叫“zhangsan”的年齡加了 2

$unset : 刪除指定的鍵

db.t_member.update({name:"zhangsan"},{$unset:{age:1}})

$push : 數組鍵操作:1、如果存在指定的數組,則爲其添加值;2、如果不存在指定的數組,則創建數組鍵,並添加值;3、如果指定的鍵不爲數組類型,則報錯;
$addToSet : 當指定的數組中有這個值時,不插入,反之插入

#則不會添加到數組裏
db.t_member.update({name:"zhangsan"},{$addToSet:{classes:"English"}}) ;

$pop:刪除指定數組的值,當 value=1 刪除最後一個值,當 value=-1 刪除第一個值

#刪除了最後一個值
db.t_member.update({name:"zhangsan"},{$pop:{classes:1}})

$pull : 刪除指定數組指定的值

#$pullAll 批量刪除指定數組
db.persons.update({name:"zhangsan"},{$pull:{classes:"Chinese"}})
#若數組中有多個 Chinese,則全刪除
db.t_member.update({name:"zhangsan"},{$pull:{classes:["Chinese"]}})

$ : 修改指定數組時,若數組有多個對象,但只想修改其中一些,則需要定位器:

db.t_member.update({"classes.type":"AA"},{$set:{"classes.$.sex":"male "}})

$addToSet 與 $each 結合完成批量數組更新操作

db.t_member.update({name:"zhangsan"},{$set:{classes:{$each:["chinese" ,"art"]}}})

runCommand 函數和 findAndModify 函數

runCommand({ 
	findAndModify:"persons",
	query:{查詢器},
	sort:{排序},
	update:{修改器},
	new:true 是否返回修改後的數據
});

runCommand 函數可執行 mongdb 中的特殊函數
findAndModify 就是特殊函數之一,用於返回執行返回 update 或 remove 後的文檔
例如:

db.runCommand({
	findAndModify:"persons",
	query:{name:"zhangsan"},
	update:{$set:{name:"lisi"}},
	new:true
})
  1. 高級查詢詳解
db.t_member.find({},{_id:0,name:1})

第一個空括號表示查詢全部數據,第二個括號中值爲 0 表示不返回,值爲 1 表示返回,默認情況下若不指定主鍵,主鍵總是會被返回;

db.persons.find({條件},{指定鍵});

比較操作符:$lt: < $lte: <= $gt: > $gte: >= $ne: !=

  • 查詢條件
#查詢年齡大於等於 25 小於等於 27 的人
db.t_member.find({age:{$gte:25,$lte:27}},{_id:0,name:1,age:1})

#查詢出所有國籍不是韓國的人的數學成績
db.t_member.find({country:{$ne:"韓國"}},{_id:0,name:1,country:1})
  • 包含與不包含(僅針對於數組)

$in 或 $nin

#查詢國籍是中國或美國的學生信息
db.t_member.find({country:{$in:["China","USA"]}},{_id:0,name:1:countr y:1})
  • $or 查詢
#查詢語文成績大於 85 或者英語大於 90 的學生信息 
db.t_member.find({$or:[{c:{$gt:85}},{e:{$gt:90}}]},{_id:0,name:1,c:1,e:1})

#把中國國籍的學生上增加新的鍵 sex
db.t_member.update({country:"China"},{$set:{sex:"m"}},false,true)

#查詢出 sex 爲 null 的人
db.t_member.find({sex:{$in:[null]}},{_id:0,name:1,sex:1})
  • 正則表達式
#查詢出名字中存在”li”的學生的信息
db.t_member.find({name:/li/i},{_id:0,name:1})
  • $not 的使用

notnot 和nin 的區別是notnot 可以用在任何地方兒nin 是用到集合上的

#查詢出名字中不存在”li”的學生的信息
db.t_member.find({name:{$not:/li/i}},{_id:0,name:1})
  • $all 與 index 的使用
#查詢喜歡看 MONGODJS 的學生
db.t_member.find({books:{$all:["JS","MONGODB"]}},{_id:0,name:1})

#查詢第二本書是 JAVA 的學習信息
db.t_member.find({"books.1":"JAVA"},{_id:0,name:1,books:1})
  • $size 的使用,不能與比較查詢符同時使用
#查詢出喜歡的書籍數量是 4 本的學生
db.t_member.find({books:{$size:4}},{_id:0,name:1})
  • 查詢出喜歡的書籍數量大於 4 本的學生本的學生

1)增加 size 鍵

db.t_member.update({},{$set:{size:4}},false,true)

2)添加書籍,同時更新 size

db.t_member.update({name:"jim"},{$push:{books:"ORACL"},$inc:{size:1} })

3)查詢大於 3 本的

db.t_member.find({size:{$gt:4}},{_id:0,name:1,size:1})
  • $slice 操作符返回文檔中指定數組的內部值
#查詢出 Jim 書架中第 2~4 本書
db.t_member.find({name:"jim"},{_id:0,name:1,books:{$slice:[1,3]}})

#查詢出最後一本書
db.t_member.find({name:"jim"},{_id:0,name:1,books:{$slice:-1}})
  • 文檔查詢

查詢出在 K 上過學且成績爲 A 的學生

1)絕對查詢,順序和鍵個數要完全符合

db.t_member.find({school:{school:"K","score":"A"}},{_id:0,name:1})

2)對象方式,但是會出錯,多個條件可能會去多個對象查詢

db.t_member.find({"school.school":"K","school.score":"A"},{_id:0,nam e:1})

正確做法單條條件組查詢$elemMatch

db.t_member.find({school:{$elemMatch:{school:"K",score:"A"}},{_id:0,name:1})

db.t_member.find({age:{$gt:22},books:"C++",school:"K"},{_id:0,name:1,
age:1,books:1,school:1})
  • 分頁與排序

1)limit 返回指定條數 查詢出 persons 文檔中前 5 條數據:

db.t_member.find({},{_id:0,name:1}).limit(5)

2)指定數據跨度 查詢出 persons 文檔中第 3 條數據後的 5 條數據

db.t_member.find({},{_id:0,name:1}).limit(5).skip(3)

3)sort 排序 1 爲正序,-1 爲倒序

db.t_member.find({},{_id:0,name:1,age:1}).limit(5).skip(3).sort({age:1})

注意:mongodb 的 key 可以存不同類型的數據排序就也有優先級

最小值->null->數字->字符串->對象/文檔->數組->二進制->對象 ID->布爾->日期->時間戳->正則->最大值

  • 遊標

利用遊標遍歷查詢數據

var persons = db.persons.find();
	while(persons.hasNext()){
	obj = persons.next();
	print(obj.name)
}

遊標幾個銷燬條件

1).客戶端發來信息叫他銷燬

2).遊標迭代完畢

3).默認遊標超過 10 分鐘沒用也會別清除

  • 查詢快照

快照後就會針對不變的集合進行遊標運動了,看看使用方法.

#用快照則需要用高級查詢
db.persons.find({$query:{name:Jim},$snapshot:true})
  1. 高級查詢選項

1)$query

2)$orderby

3)$maxsan:integer 最多掃描的文檔數

4)$min:doc 查詢開始

5)$max:doc 查詢結束

6)$hint:doc 使用哪個索引

7)$explain:boolean 統計

8)$snapshot:boolean 一致快照

  • 查詢點(70,180)最近的 3 個點
db.map.find({gis:{$near:[70,180]}},{_id:0,gis:1}).limit(3)
  • 查詢以點(50,50)和點(190,190)爲對角線的正方形中的所有的點
db.map.find({gis:{$within:{$box:[[50,50],[190,190]]}}},{_id:0,gis:1})
  • 查詢出以圓心爲(56,80)半徑爲 50 規則下的圓心面積中的點
db.map.find({gis:{$with:{$center:[[56,80],50]}}},{_id:0,gis:1})
  1. Count+Distinct+Group
  • count 查詢結果條數
db.persons.find({country:"USA"}).count()
  • Distinct 去重

請查詢出 persons 中一共有多少個國家分別是什麼

#key 表示去重的鍵
db.runCommand({distinct:"persons",key:"country"}).values
  • group 分組
db.runCommand({ group:{
	ns:"集合的名字",
	key:"分組鍵對象",
	initial:"初始化累加器",
	$reduce:"分解器",
	condition:"條件",
	finalize:"組完成器"
}})

分組首先會按照 key 進行分組,每組的 每一個文檔全要執行$reduce 的方法,他接收 2 個參數一個是組內本條記錄,一個是累加器數據.

請查出 persons 中每個國家學生數學成績最好的學生信息(必須在 90 以上)

db.runCommand({
	group:{
	ns:"persons",
	key:{"country":true},
	initial:{m:0},
	$reduce:function(doc,prev){
		if(doc.m>prev.m){
			prev.m = doc.m;
			prev.name = doc.m;
			prev.country = doc.country;
		}
	},
	condition:{m:{$gt:90}},
	finalize:function(prev){
		prev.m = prev.name+" comes from "+prev.country+" ,Math score is"+prev.m;
		}
	}
})
  • .函數格式化分組鍵

如果集合中出現鍵 Counrty 和 counTry 同時存在

$keyf:function(doc){
	if(doc.country){
		return {country:doc.country}
	}

return {country:doc.counTry}
}
  1. 常用命令舉例
  • 查詢服務器版本號和主機操作系統
db.runCommand({buildInfo:1})
  • 查詢執行集合的詳細信息,大小,空間,索引等
db.runCommand({collStats:"persons"})
  • 查看操作本集合最後一次錯誤信息
db.runCommand({getLastError:"persons"})
  1. 固定集合
  • 特性

固定集合默認是沒有索引的就算是_id 也是沒有索引的,由於不需分配新的空間他的插入速度是非常快的

固定集合的順是確定的導致查詢速度是非常快的

最適合就是日誌管理

  • 創建固定集合

創建一個新的固定集合要求大小是 100 個字節,可以存儲文檔 10 個

db.createCollection("mycoll",{size:100,capped:true,max:10})

把一個普通集合轉換成固定集合

db.runCommand({convertToCapped:"persons",size:1000})
  • 對固定集合反向排序,默認情況是插入的順序排序
db.mycoll.find().sort({$natural:-1})

常見問題總結

Mongo和ES對比

elasticsearch 純粹的是json(字符串),而mongo結構更加複雜

mongo的優勢是哪些?

  • BSON
  • GirdFS(複雜性的體現)

用戶手機註冊驗證碼存取適合用mongo嗎?還是redis?

建議用Seesion,用Redis過時時間,不推薦用MongoDB

MongoDB應用場景

  • 不規則日誌:ELK, Log4J INFO,ERROR,WARN,DEBUG(字符串?)

    Pattern,用正則去解析字符串,不止一個正則,
    每一種日誌格式都要編寫一個正則去匹配
    既然用正則麻煩,爲什麼還用ELK存儲日誌?
    因爲可能你的系統已經平穩運行N年了(.Net,PHP、Java多語言交錯,情況複雜)

  • 規則日誌:MongoDB,結構化的整理,

    用戶行爲日誌 operationTime creator type target
    Timline,調用鏈路 invoker Time targetMethod args returnVal throws

  • 持續增量(id + UpdateTime)

  • 文件存儲:GirdFS(文件存儲系統)

  • 不適合Reids:數據需要持久性的而且有一定的依賴性
    適合Redis:數據會設置時效
    分佈式鎖
    用戶登錄token
    數據庫緩存中間件

MongoDB(GridFS)、Hadoop、HBase對於數據存儲得使用場景選擇嗎?

定位:
MongoDB,爲一個結構化的緩存,由於設計原理不同,數據量是一定的瓶頸的。
HBase ,基於列簇擴展性,高可用程度會更加靈活,數量級和MongoDB也是有很大差異的。

HBase 通常會跟大數據聯繫在一起
MongoDB 頂多算是一個日誌數據庫,文件存儲系統

Mongo怎麼持久化的?

持久化都是用文件的形式存儲,其實任何數據庫都是用文件實現持久化的

後記

更多架構知識,歡迎關注本套Java系列文章,地址導航Java架構師成長之路

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章