1. 程式人生 > >MongoDB學習記錄一

MongoDB學習記錄一

users 泰安 系統設置 2.3 默認端口 erp nec acl 負責

本博客說明:最開始部分是一個運維部署案例模板,給開發安裝MongoDB都可以按照這個模板來進行基本部署,中間部分是自己研究其他博客記錄部署和授權相關內容,最後部分是網上視頻學習相關內容;
www.mongodb.org 下載地址
案例安裝一個完整MongoDB所做操作;
1.上傳解壓
tar -zxvf mongodb-linux-x86_64-3.0.6.tgz -C /home/
cd /home && mv mongodb-linux-x86_64-3.0.6 mongodb
2.創建所需目錄
cd / && mkdir /home/mongodb/conf
創建數據存儲目錄了
cd /home/ && mkdir -p data/db
創建log存放目錄cd /home/mongodb/ && mkdir log
3.編寫配置文件
vim /home/mongodb/conf/mongodb.conf
dbpath=/home/data/db
port=27017
fork=true
logappend=true
pidfilepath=/home/mongodb/run/mongo.pid
logpath=/home/mongodb/log/mongodb.log

4.啟動MongoDB
# ./mongod -f /usr/local/mongodb/conf/mongodb.conf
5.進入MongoDB的shell
/usr/local/mongodb/bin/mongo 進入shell
show dbs

5.添加管理用戶----這個用戶admin只能管理用戶,沒有其他操作權限,對數據庫沒有操作權限
> use admin
switched to db admin
>db.createUser(
{
user:"admin",
pwd:"123456",
roles:[{role:"userAdminAnyDatabase",db:"admin"}]
}
)

user:指定用戶名
pwd:指定用戶密碼
roles:指定角色名稱以及角色的認證庫

6.完善認證配置
當創建完一個高權限用戶後就可以開啟認證了,在配置文件中添加參數auth參數,然後重啟mongod
#echo "auth = true" >> /usr/local/mongodb/conf/mongodb.conf
7.重啟MongoDB
關閉MongoDB千萬不要kill -9 pid,可以kill -2 pid或db.shutdownServer()
重啟MongoDB
/home/mongodb/bin/mongo---進入shell
use admin
db.shutdownServer()
exit---------------------------退出
/home/mongodb/bin/mongod -f /home/mongodb/conf/mongodb.conf ------啟動
8.進入mongo shell進行認證
/usr/local/mongodb/bin/mongo
進行認證,需要註意在那個庫創建的用戶就需要在那個庫進行認證;
認證方法一:
> use admin
> db.auth("admin","123456")
1 -------認證,返回1表示成功
認證方法二:
/home/mongodb/bin/mongo -u admin -p 123456 --authenticationDatabase admin

9.創建用戶
下面創建用戶,用戶都跟著庫走,創建用戶test1案例如下
use test -----這個是進入test庫,也是新建給test數據庫
db.createUser(
{
user:"test1",
pwd:"test1",
roles:[
{role:"readWrite",db:"test"}
]
}
)


10.查看相關命令
./mongo -u admin -p 123456 --authenticationDatabase admin
use admin
db.system.users.find().pretty()
查看
db.system.roles.find();
查看角色
db.getRole("test",{showPrivileges:true})
查看用戶
下面切換到admin下查看剛才創建的用戶
> use admin
> show users

查看整個MongoDB全部用戶
use admin
> db.system.users.find().pretty()
11.角色授權
db.grantPrivilegesToRole(
{
role:"test",
privileges:[
{
resource:{
db:"wallet",
collection:""
},
actions:["createCollection","dropCollection","convertToCapped"]
}
],
roles:[]
}
)

12.驗證
創建完畢之後驗證
> use test
switched to db test
> db.auth("test1","test1")
> show collections 沒報錯就證明授權成功

13.刪除相關命令
刪除角色
use admin
use test
db.dropRole("test")
刪除用戶
>use admin
>use test
> db.dropUser(‘test1‘)
true
還可以使用db.dropAllUsers()刪除當前庫的所有用戶,如下:
>use admin
>db.dropAllUsers()
1
就可以把admin庫的所有用戶都刪除掉;

14.用戶密碼修改
利用db.changeUserPassword()可以修改用戶的密碼,如下:
db.changeUserPassword(‘admin‘,‘123‘)


註意:在MongoDB中刪除庫和集合並不會級聯刪除對應的角色和用戶,如果想要徹底刪除對應的業務庫,應該先刪除庫及對應的角色和用戶。
如果既想實現精細化權限,又想簡化用戶管理,原則上可以給開發創建一個賬戶,並且使用admin做認證庫,這樣可避免清理過期業務庫而導致無法登陸的問題;


中間部分
1.MongoDB權限介紹
MongoDB3之前的權限控制簡單粗暴,只能給開發提供最高權限,從MongoDB3開始在權限控制這塊已完善很多;
1.1關鍵字理解如下:
user:用戶,用於提供客戶端連接MongoDB的認證賬戶;
role:角色,數據權限的集合,創建用戶的時候必須指定對應的角色,否則用戶無法操作數據庫;
resource:資源,包括database或collection也可以是database和collection的組合;例如:{db:<database>,collection:<collection>},當然也可能看到一種特殊的資源:{"cluster":true},表示全局資源;
actions:權限操作,定義了"user"能夠對"resource ;document"執行的操作,例如:增刪改查包括如下操作:find/insert/remove/update;
privilege:權限,是一組"resource"和"actions"的組合;
authenticationDatabase:認證庫,即創建角色或用戶時所在的庫;例如在admin下創建了MongoDB用戶,那麽登陸的時候需要執行認證庫;
1.2用戶角色說明
角色就是對某一資源權限的"集合",MongoDB中有兩種角色,一種是知道的角色,一種是自定義的角色;
1.2.1內置角色介紹
A:read:數據庫只讀權限,包括如下:
aggregate,checkShardingIndex,cloneCollectionAsCapped,collStats,count,dataSize,dbHash,dbStats,distinct,filemd5,mapReduce(inline output only),text(beta feature)geoNear,geoSearch,geoWalk,group;

B:readWrite:數據庫的讀寫權限,包含read角色的所有權限,包括如下:
cloneCollection(as the target database),convertToCapped,create(and to create collections inplicitly),renameCollection(within the same database)findAndModify,mapReduce(output to a collection),drop(),dropIndexes,emptycapped,ensureIndex();

C:dbAdmin:數據庫的管理權限,包括如下:
clean,collMod,collStats,compact,convertToCappe,create,db.createCollection(),dbStats,drop(),dropIndexes,ensureIndex(),indexStats,profile,reIndex,renameCollection(within a single database),validate;

D:userAdmin:數據庫的用戶管理權限;

E:clusterAdmin:集群管理權限(副本集、分片、主從等相關管理);

F:readAnyDatabase:任何數據庫的只讀權限,和read相似,區別這裏是全局的;

G:readWriteAnyDatabase:任何數據庫的讀寫權限,和readWrite相似,這裏是全局的;

H:userAdminAnyDatabase:任何數據庫的管理權限,與dbAdmin相似,這裏是全局的;

I:dbAdminAnyDatabase:任何數據庫的管理權限,dbAdmin相似,這裏是全局的;

J:backup、restore:數據的備份和恢復權限;

K:root:超級用戶權限,只能針對admin庫;

1.2.2自定義角色
正常情況下MongoDB內置角色就夠用了,當內置角色不能滿足需求時可以自定義角色
自定義角色語法如下:
use admin-----------------------------------------------------#進入admin數據庫;
db.createRole(
{
role:<role_name>,------------------------------------#定義角色的名稱
privileges:[-----------------------------------------#權限集
{resource:{db:<db_name>,collection:<coll_name>},-#定義這個據說要控制的庫和集合,集合為""時表示全部;
actions:[----------------------------------------#定義對這個庫或集合可進行的權限操作,這裏是一個數組;
<action_name>
]
}
],
Roles:[{role:<role_name>,db:<db_name>}]--------------#是否繼承其他的角色,如果指定了其他角色那麽新創建的角色自動繼承對應其他角色的所有權限,該參數必須顯示指定;
}
)
}

)
舉例說明如下:
use admin
db.createRole(
{
role:"test",
privileges:[
{resource:{
db:"wallet",
collection:""
},
actions:["find","insert","remove","update"]
}
],
roles:[]
}
)
解釋:上述語句在admin庫裏創建了一個名為test的角色,該角色具有對數據庫wallet下的所有集合進行find,insert,remove,update的操作權限。角色創建完畢後MongoDB會在系統庫admin下創建一個系統collection名叫system.roles,裏面存儲的即是角色相關的信息,可以使用如下語句進行查看
db.system.roles.find();
1.3操作角色
以下操作都基於admin庫
A:查看角色
db.getRole("test",{showPrivileges:true})

B:角色繼承
設置角色test1繼承test:
db.grantRolesToRole("test1",["test"])
基於test角色移除test1角色
db.revokeRolesFromRole("test1",["test"])

C:角色授權
db.grantPrivilegesToRole(
{
role:"test",
privileges:[
{
resource:{
db:"wallet",
collection:""
},
actions:["createCollection","dropCollection","convertToCapped"]
}
],
roles:[]
}
)

D:角色移權
db.revokePrivilegesFromRole(
{
role:"test",
privileges:[
{
resource:{
db:"wallet",
collection:""
},
actions:["createCollection","dropCollection","convertToCapped"]
}
],
roles:[]
}
)

E:刪除角色
db.dropRole("test")

2.mongodb單實例認證
裝好MongoDB之後一定不要在配置中加auth=true,做好授權賬號密碼之後再開啟用戶認證;
原因如下:
MongoDB安裝時不添加任何參數,默認沒有權限驗證,登陸用戶可以對數據庫任意操作,剛安裝完畢時MongoDB都默認有一個admin數據庫,此時admin數據庫是空的,沒有記錄權限相關信息,當admin.system.users一個用戶都沒有時,這時mongod啟動時配置文件中加了auth = true認證就麻煩了;
因為MongoDB的訪問分為認證和授權,所以使用auth參數開啟認證後,雖然還可以不進行認證直接進入數據庫,但是不會有任何權限進行操作,當執行命令時會報如下錯誤:
not authorized on admin to execute command
一旦開啟認證後授權就會生效,如果登陸時沒進行用戶認證,那麽就沒有任何權限執行任何命令。

異常處理:出現上述說的第一次裝好啟動時就設置auth = true認證之後可以處理的方式有如下兩種:
方法一:
關掉MongoDB,先添加完用戶再開啟用戶認證;
方法二:
MongoDB提供了一個參數在開啟認證的情況下允許本地連接MongoDB,就是使用localhost連接,其余一律不接受,此時把這兩個參數同時使用上即可尅器認證時沒有添加任何用戶的情況下允許本地五人制連接進行數據庫操作:
auth = true
SetParameter=enableLocalhostAuthBypass=1
註意:上面兩個參數使用有如下條件限制:
A:這個參數值能在開啟認證的情況,並且沒有任何用戶的情況下才生效,否則無效;
B:滿足第一個條件時,只允許本地以localhost的方式進行連接MongoDB,否則無效;
C:滿足第一個條件時,當進入到MongoDB後如果創建了一個用戶後,此參數將失效,就是本地無法登陸了;
D:以此方式創建的用戶必須是admin庫的,同時必須能夠具備創建其他用戶的權限;

在MongoDB授權時需要註意版本兼容問題:
admin數據庫中的用戶名可以管理所有數據庫,其他數據庫中的用戶只能管理其所在的數據庫;在2.4版本之前用戶的權限分為只讀和擁有所有權限,2.4版本的權限管理主要分為:數據庫的操作權限、數據庫用戶的管理權限、集群的管理權限,建議由超級用戶在admin數據庫中管理這些用戶。

3.MongoDB復制集認證
註意:開啟KeyFile認證之後無需再開啟auth認證;

這裏所說的就是在MongoDB集群中認證方式;在復制集機制下開啟auth = true認證後,MongoDB復制集狀態會變成不健康狀態,這就需要梁歪以這個認證方式"KeyFile";簡單來說"KeyFile"就是用在復制集群間開啟認證的情況下需要的另外一種認證方式,用來驗證集群間身份;在復制集模式下開啟KeyFile之後就不需要再開啟auth了,因為開啟KeyFile後就會自動開啟認證功能。
開啟KeyFile的方法:需要在每個節點主機上創建一個文件,然後給一些字符串,但是復制集各個節點上的字符串必須相同才能進行身份驗證,如下方法生成一個KeyFile:
#echo "this is a keyfile" > /usr/local/mongodb/.KeyFile
生成KeyFile時需要註意,不用在意空格、tab、以及換行符,KeyFile會自動去掉;
KeyFile註意事項:
A:內容:base64編碼,所以不能超出這個範圍[a-zA-Z+/]
B:長度:1000bytes
C:權限:chmod 600 KeyFile
KeyFile生成好之後,就可以同步到各個節點間了,然後在各個節點的配置文件中把KeyFile文件制定進來即可
keyFile=/usr/local/mongodb/.KeyFile
SetParameter=enableLocalhostAuthBypass=1
然後給權限600即可
#chmod 600 /usr/local/mongodb/.KeyFile

再次提醒註意:開啟了KeyFile後就不需要添加auth=true參數了,默認會開啟認證;然後重啟復制集各個節點就完成認證;

在復制集模式下,在整個認證配置完成之前不要創建任何用戶,當整個認證好了之後,下面再創建用戶;

4.MongoDB創建和刪除用戶
下面所有內容都是MongoDB3.0+以上版本
4.1不開啟認證進行用戶創建
4.1.1創建用戶並啟動
首先需要我們在不認證的情況下,在admin庫中創建一個高權限用戶,也就是需要在不認證情況下啟動MongoDB,下面給出一個簡單的配置文件
#/usr/local/mongodb/conf/mongodb.conf
dbpath=/usr/local/mongodb/db
port=27017
fork=true
logappend=true
#auth = true
pidfilepath=/usr/local/mongodb/run/mongo.pid
logpath=/usr/local/mongodb/log/mongodb.log

#mkdir -p /data/db
#chown mongod.mongod /usr/local/mongodb/db -R

啟動MongoDB
# ./mongod -f /usr/local/mongodb/conf/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 40969
child process started successfully, parent exiting
4.1.2打開mongo shell
#/usr/local/mongodb/bin/mongo
接著在命令窗口中輸入:
> show dbs
local 0.078GB
看到只有一個local數據庫,admin是不存在的(這是3.0以上版本改變了的),我們需要自己給他創建個admin數據庫。

4.1.3添加管理用戶
> use admin
switched to db admin
>db.createUser(
{
user:"admin",
pwd:"123456",
roles:[{role:"userAdminAnyDatabase",db:"admin"}]
}
)
下面是執行成功後顯示出來的內容
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}

user:指定用戶名
pwd:指定用戶密碼
roles:指定角色名稱以及角色的認證庫

4.1.4查看用戶
下面切換到admin下查看剛才創建的用戶
> use admin
> show users
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
或者這樣查詢也可以
> db.system.users.find().pretty()
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "eosukXNkKY0aVWsZ18Dz4Q==",
"storedKey" : "L3okXSu5LDP/Lxpr6LYwwBMkKVc=",
"serverKey" : "IanvYr6fiD4RzjbF9TuN8omIvZA="
}
},
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}

4.1.5關閉MongoDB
千萬不要kill -9 pid,可以kill -2 pid或db.shutdownServer()

4.2開啟認證,進行用戶認證
4.2.1使用auth參數啟動MongoDB
當創建完一個高權限用戶後就可以開啟認證了,在配置文件中添加參數auth參數,然後重啟mongod
#echo "auth = true" >> /usr/local/mongodb/conf/mongodb.conf

重啟MongoDB
/usr/local/mongodb/bin/mongo
> use admin
switched to db admin
> db.shutdownServer()
> exit
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/conf/mongodb.conf

4.2.2打開mongo shell進行認證
/usr/local/mongodb/bin/mongo
進行認證,需要註意文明在那個庫創建的用戶就需要在那個庫進行認證;
認證方法一:
> use admin
> db.auth("admin","123456")
1 -------認證,返回1表示成功
認證方法二:
#/usr/local/mongodb/bin/mongo -u admin -p 123456 --authenticationDatabase admin


此時認證完畢之後查看下面的會報錯,原因是用戶admin只有用戶管理的權限;
> show collections
2018-09-07T14:37:53.049+0800 E QUERY Error: listCollections failed: {
"ok" : 0,

4.2.3創建用戶
下面創建用戶,用戶都跟著庫走,創建用戶test1案例如下
use test -----這個是進入test庫,也是新建給test數據庫
db.createUser(
{
user:"test1",
pwd:"test1",
roles:[
{role:"readWrite",db:"test"}
]
}
)
創建成功的標誌
Successfully added user: {
"user" : "test1",
"roles" : [
{
"role" : "readWrite",
"db" : "test"
}
]
}

4.2.4查看剛才創建的用戶
> show users
{
"_id" : "test.test1",
"user" : "test1",
"db" : "test",
"roles" : [
{
"role" : "readWrite",
"db" : "test"
}
]
}

4.2.5查看整個MongoDB全部用戶
use admin
> db.system.users.find().pretty()
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "eosukXNkKY0aVWsZ18Dz4Q==",
"storedKey" : "L3okXSu5LDP/Lxpr6LYwwBMkKVc=",
"serverKey" : "IanvYr6fiD4RzjbF9TuN8omIvZA="
}
},
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
{
"_id" : "test.test1",
"user" : "test1",
"db" : "test",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "Ha9L2oBgzfsg4E4NmqK2EQ==",
"storedKey" : "91tlI5351t6yLjsufxifxEXzFTw=",
"serverKey" : "NV7YRm7230NMsWGPHD0VnhLpOrg="
}
},
"roles" : [
{
"role" : "readWrite",
"db" : "test"
}
]
}

4.2.6驗證
創建完畢之後驗證
> use test
switched to db test
> db.auth("test1","test1")
> show collections 沒報錯就證明授權成功

5.查看用戶
> use admin
switched to db admin
> db.getUser("admin")
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
6.用戶密碼修改
利用db.changeUserPassword()可以修改用戶的密碼,如下:
db.changeUserPassword(‘admin‘,‘123‘)

7.刪除用戶

提醒:
修改和刪除用戶等操作,都和創建用戶一樣,需要先切換到數據庫管理員的身份,即admin庫,之後才能進行後面的操作,同樣需要到對應數據庫中才能刪除掉用戶,因為用戶是跟著庫走的;

使用db.dropUser(<user_name>)進行指定用戶刪除
>use admin
>use test
> db.dropUser(‘test1‘)
true
還可以使用db.dropAllUsers()刪除當前庫的所有用戶,如下:
>use admin
>db.dropAllUsers()
1
就可以把admin庫的所有用戶都刪除掉;

註意:在MongoDB中刪除庫和集合並不會級聯刪除對應的角色和用戶,如果想要徹底刪除對應的業務庫,應該先刪除庫及對應的角色和用戶。
如果既想實現精細化權限,又想簡化用戶管理,原則上可以給開發創建一個賬戶,並且使用admin做認證庫,這樣可避免清理過期業務庫而導致無法登陸的問題;

查看
./mongo -u admin -p 123 --authenticationDatabase admin
use admin
db.system.users.find().pretty()

最後部分
本記錄為網上學習MongoDB入門課程筆記;
dos裏面清屏cls
1.概念
MongoDB在數據庫發展初期就已經存在了,SQL語句使用簡單,就是幾個簡單的單詞:select,from,where,group by,having,order by;
NoSQL:not only sql
數據庫讀取流程:數據讀取----POJO(VO、PO)----控制層轉化為json數據----客戶端
上面這樣的數據轉換為json比較麻煩,使用MongoDB這種NoSQL數據庫直接存放json數據,取出來就是json數據,無需轉換可直接使用;NoSQL負責數據的讀取;NoSQL按照指定的結構進行存儲數據;
概念之關系型數據庫和NoSQL比較:
關系型數據庫(mysql&oracle) NoSQL數據庫
數據庫 數據庫(類似語句MySQL)
表 集合
行 文檔
列 成員
主鍵 Object ID(自動維護)


所有的NoSQL數據庫中MongoDB是發展最好的,因為MongoDB數據庫與Node.JS捆綁在一起了,即要從事Node.JS的開發,就一定要用到MongoDB,而Node.JS(基於JavaScript)在國內比較流行;
MongoDB是面向集合的存儲過程、模式自由(無模式)、方便的進行數據存儲擴容、支持索引、支持短暫數據保留、具備完整的數據庫狀態監控、基於BSON應用。國內最成功的應用是淘寶;
2.MongoDB的安裝和配置
2.1下載:www.mongodb.org
版本介紹:3.0.x變成了windows安裝版;這裏只是把原來的2.6.4解壓縮版本變成了安裝拷貝,原來的mongodb-win32-i386-2.6.4zip直接下載打開即可使用;現在都3.0.x安裝版安裝之後和原來的2.6.4解壓縮版解壓之後一樣;------糾正,目前官網已經更新分不同系統

2.2安裝:安裝的時候需要選擇對應的操作系統;這個軟件是誇操作系統的,使用那個版本都可以;Linux上面啟動後有個守護進程,這個守護進程在windows上面沒有;
windows安裝3.0版本:安裝選擇下一步----選擇"custom"-----E:\MongoDB\-----安裝完成----備註:如果是2.6.4解壓之後和這裏安裝好之後一樣,所以2.6.4直接解壓之後使用即可;
配置環境變量:選擇"計算機"右鍵選擇"屬性"-----"高級系統設置"----"環境變量"-----選擇"系統變量"下的"Path"------變量值這裏填寫E:\MongoDB\bin;放到最前面
2.3啟動MongoDB:
啟動的前提條件是先在E:\MongoDB目錄下建立一個db文件夾;啟動之後的數據都放到這個db文件夾下;啟動使用的程序是mongod.exe,商用需要啟動對應的參數:端口號、是否啟用用戶驗證、數據文件的位置等等。
在E:\MongoDB\目錄下建立一個mongodb.conf文件,在這個文件中寫上配置內容;
在E:\MongoDB\目錄下建立一個log目錄,在log目錄下建一個文件為mongodb.log
下面編寫配置mongodb.conf
# 設置數據目錄路徑
dbpath = E:\MongoDB\db
# 設置日誌信息文件路徑,本行設置和下一行設置共同決定是否需要將日誌輸出到mongodb.log中
logpath = E:\MongoDB\log\mongodb.log
# 打開日誌輸出操作
logappend = true
# 是否需要登陸認證noauth = true表示不需要登陸認證,在以後進行用戶管理使用
noauth = true
# 端口號設置
port = 27001

重啟步驟:
進入到MongoDB的shell界面下之後執行如下三步命令即可
A:切換到admin數據庫:use admin
B:關閉數據庫服務:db.shutdownServer()
C:啟動服務:mongod -f e:\MongoDB\mongodb.conf

這時連接方式:mongo --port=27001


啟動方式一:不設置端口號啟動MongoDB服務
mongod --dbpath E:\MongoDB\db -----這時啟動的時候就使用它默認端口號27000
啟動方式二:設置端口號啟動MongoDB服務(商用)
mongod --dbpath E:\MongoDB\db --port=27000
2.4連接MongoDB
cmd-----mongo進行連接或者指定端口號mondo --port=27000出現如下命令為正常連接
MongoDB shell version:3.0.3
connecting to:test -----進來就默認連接到test這個數據庫
2.5MongoDB命令
MongoDB命令區分大小寫,很多和mysql一樣;
查詢有那些數據庫show databases;會看到沒有數據庫,這時制存在一個local的本地數據庫,這個數據庫不使用;

3.MongoDB基礎操作
MongoDB裏面有數據庫的概念,但是沒有模式(所有的信息都按照文檔進行保存),數據結構就是json數據結構;只有在進行一些數據處理時才會使用到MongoDB自己的操作符合;
3.1使用mldn數據庫
use mldn
實際在這個時候並不會創建數據庫,只有在數據庫裏面保存集合數據之後
3.2創建集合[正常不這樣使用]
演示創建一個emp集合:db.createCollection("emp");
正常使用方式是直接往裏面存放數據,不是先創建數據庫,然後再往數據庫裏面存數據,因為MongoDB是無模式的;這裏我直接向裏面保存一個數據:db.dept.insert({"deptno":10,"dname":"財務部","loc":"北京"});

這裏可以隨意擴充數據
3.3查看所有集合
查詢show collections;
這時會看到dept集合自動創建了;

3.4查看emp表的數據
語法:db.集合名稱.find({若幹條件})
db.dept.find(); ---不寫條件時這樣查詢
查看單獨的一個數據:db.dept.findOne();
3.5增加不規則數據
var deptData = {
"deptno":20,
"dname":"研發部",
"loc":"深圳",
"count":20,
"avg":8000.0
};
db.dept.insert(deptData);
直接執行上面的內容即可插入數據;再次查看show collections;
因為可以隨意的添加數據,集合結構沒有要求,所以MongoDB中沒有查看集合結構的命令,MongoDB是無模式的集合;
3.6關於id問題
在MongoDB集合中的每一行記錄都會自動生成一個objectid,其組成是:"時間戳+機器碼+PID+計數器",這個id的信息是MongoDB數據庫自己為用戶生成,不需要維護;
3.7數據刪除
數據的刪除和修改都很麻煩;
範例:刪除數據db.dept.remove({"id":ObjectId("32434deeggsfdgrgc7898")});
後面會講解其他的刪除方法
3.8數據修改
數據修改的意義不大
var deptDate = {
"deptno":50,
"dname":"乞討",
"loc":"家裏",
"count":60,
"avg":9000.0
};
db.dept.update({"id":ObjectId("32434deeggsfdgrgc7898")},deptDate);
3.9刪除集合
語法:db.集合名稱.drop()
範例:db.dept.drop();
查看show collections;
3.10刪除數據庫(刪除當前所在的數據庫)
必須先切換到某個數據庫之後才能刪除這個數據庫
db.dropDatabse()
查看show dbs;
4.數據操作(重點)
數據庫的核心操作CRUD
對應MongoDB除了增加數據比較簡單,其他的操作都很麻煩,修改是最麻煩的;
4.1數據增加
語法:db.集合.insert()

範例:
use mldn;
db.infos.insert({"url":"www.mldn.cn"});
db.infos.find();
以數組的形式增加
db.infos.insert([
{"url":"www.mldn.cn"},
{"url":"www.mldnjava.cn"}
]
}
);
db.infos.find();
要保存多個數據就使用數組的形式進行保存
範例保存10000條數據,這時使用JavaScript實現
直接執行下面命令即可;
for (var x = 0 ; x < 10000 ; x++){
db.infos.insert({"url" : "mldn -" + x});
}
查詢db.infos.find();這裏可以通過輸入it翻頁;如果數據保存很多的情況下,列表時不會全部列出,只會列出部分內容,可以通過it翻頁查看更多數據;
4.2數據查詢
mongodb中數據查詢比較方便,有關系運算、邏輯運算、數組運算、正則運算等。
查詢操作核心語法:"db.集合名稱.find({查詢條件}[,{設置顯示的字段}])"
範例:最簡單的用法就是直接使用find()函數完成查詢
db.infos.find()
範例:查詢出url為"www.mldn.cn"的數據
db.infos.find({"url":"www.mldn.cn"});
在數據查詢的時候也是按照json格式設置相等關系;
對於設置的顯示字段嚴格來講就稱為數據的投影操作;例如我查詢一個數據時可以只顯示其中一部分,只把部門名稱和員工顯示出來,員工的收入不顯示出來;不需要顯示的字段設置為"0" 需要顯示的字段設置為"1"
範例:不顯示id----db.infos.find({"url":"www.mldn.cn"},{"_id":0});
db.infos.find({"url":"www.mldn.cn"},{"_id":0,"url":1});
上面這種投影操作意義不大,不建議使用
對於數據的查詢還可以使用pretty()函數;
範例:db.infos.find({"url":"www.mldn.cn"},{"_id":0,"url":1}).pretty();----這樣查詢出來的數據就會先對其進行格式化之後再顯示,
4.2.1關系查詢
在MongoDB中支持的關系操作:大於($gt)、小於($lt)、大於等於($gte)、小於等於($lte)、不等於($ne)、等於(key:value或$qe).
範例:準備數據
db.students.drop();
db.students.insert({"name":"李白","sex":"男","age":19,"score":80,"address":"深圳"});
db.students.insert({"name":"杜甫","sex":"男","age":20,"score":50,"address":"中山"});
db.students.insert({"name":"李清照","sex":"女","age":88,"score":60,"address":"北京"});
db.students.insert({"name":"駱賓王","sex":"女","age":66,"score":30,"address":"上海"});
db.students.insert({"name":"王炯","sex":"男","age":33,"score":50,"address":"珠海"});
db.students.insert({"name":"張三","sex":"男","age":45,"score":70,"address":"駐馬店"});
db.students.insert({"name":"李四","sex":"男","age":34,"score":40,"address":"鄭州"});
db.students.insert({"name":"王五","sex":"女","age":34,"score":70,"address":"西安"});
db.students.insert({"name":"狗拽","sex":"男","age":65,"score":80,"address":"山西"});
db.students.insert({"name":"小明","sex":"女","age":65,"score":80,"address":"新疆"});
db.students.insert({"name":"小黃","sex":"女","age":54,"score":90,"address":"泰安"});
db.students.insert({"name":"小白","sex":"男","age":52,"score":60,"address":"青島"});
db.students.insert({"name":"小紅","sex":"女","age":51,"score":70,"address":"濰坊"});
範例一:
db.students.find({"name":"張三"}).pretty();
範例二:查詢性別是男的
db.students.find({"sex":"男"}).pretty();
範例三:查詢年齡大於20的
db.students.find({"age":{"$gt":20}}).pretty();
範例四:查詢成績高於60的
db.students.find({"score":{"$gte":60}}).pretty();
範例五:查詢行嗎不是王五的信息
db.students.find({"name":{$ne:"王五"}}).pretty();
註意:在一個json結構裏面需要定義其他條件的時候依然是json結構;
4.2.2邏輯運算
邏輯運算主要有三種類型:與($and)、或($or)、非($not、$nor)
範例1:查詢年齡在19~20的學生信息
db.students.find({"age":{"$gte":19,"$lte":19}}).pretty();
在進行邏輯運算的時候"and"的連接比較容易,只需要利用","分隔即可;
範例2:查詢年齡不是19歲
db.students.find({"age":{"$ne":19}}).pretty();
範例3:查詢年齡大於19歲或者成績大於90分的
db.students.find({"or",[
{"age":{"$gt":19}},
{"score":{"$gt":90}}
]}).pretty();
4.2.3非運算
範例4:對案例3進行求反,得到成就小於等於19且成就小於等於90
db.students.find({"nor",[
{"age":{"$gt":19}},
{"score":{"$gt":90}}
]}).pretty();

上面邏輯運算中"與"比較簡單,"或"和"非"稍微復雜一些,需要一個數組來設置條件;
4.2.4求模
模的運算使用"$mod"來完成
語法:{$mod:[數字,余數]}
範例1:求對20求模之後與1的,即21,41這些
db.students.find({"age":{"$mod":[20,1]}}).pretty();
利用求模運算可以編寫一些數學的計算公式;
4.2.5範圍查詢---工作中很重要
只要是數據庫,都存在"$in"(在範圍之中)、"$nin"(不在範圍之中)
範例一:查詢姓名是"張三""李四""王五"
db.students.find({"name":{"$in":["張三","李四","王五"]}}).pretty();
範例二:查詢姓名不是"張三""李四""王五"
db.students.find({"name":{"$nin":["張三","李四","王五"]}}).pretty();
4.2.6數組查詢
MongoDB中支持數組保存;
素材準備
db.students.insert({"name":"鐵拐李-A","sex":"男","age":19,"score":60,"address":"深圳","course":["語文","數學","英語","政治"]});
db.students.insert({"name":"鐵拐李-B","sex":"男","age":20,"score":60,"address":"深圳","course":["語文","數學"]});
db.students.insert({"name":"鐵拐李-C","sex":"男","age":21,"score":60,"address":"深圳","course":["語文","數學","英語"]});
db.students.insert({"name":"鐵拐李-D","sex":"男","age":22,"score":60,"address":"深圳","course":["語文","數學","英語","政治"]});
db.students.insert({"name":"鐵拐李-E","sex":"男","age":23,"score":60,"address":"深圳","course":["英語","政治"]});
db.students.insert({"name":"鐵拐李-F","sex":"男","age":24,"score":60,"address":"深圳","course":["語文","政治"]});

查詢:db.students.find().pretty();
下面對數組中數據進行判斷可以使用如下運算符:
$all,$size,$slice,$elemMatch
範例一:查詢同時參加語文和數學----{"$all",["內容1","內容2",...]}
db.students.find({"course":{"$all":["語文","數學"]}}).pretty();
只要是有語文和數學這兩門的都會查出來,其他的有沒有不管;但是語文和數學少一個都不會顯示出來;
案例二:查詢學生地址是深圳的
$all可以用在數組上,也可以用在數據的匹配上
db.students.find("address":{"$all":["深圳"]}).pretty();
案例三:查詢數組中第二個內容(index=1,索引下標從0開始)為數學的信息;
既然是數組就可以使用索引來進行操作,即"key.index"來定義索引
db.students.find({"course.1":"數學"}).pretty();
範例四:查詢只參加兩門課程的學習-----$size 計數
db.students.find({"course":{"$size":2}}).pretty();
範例五:查詢返回年齡為19所有學生信息中只顯示參加的前兩門課程------$slice
對查詢返回數據內容數量進行控制,例如返回三個數據我只需要顯示兩個數據
db.students.find({"age":19},{"course":{"$slice":2}}).pretty();
如果年齡為19的學生參加的課程超過2門,那麽只顯示前兩門課程,後面的不顯示
範例六:查詢返回年齡為19所有學生信息中只顯示參加的後兩門課程------$slice
db.students.find({"age":19},{"course":{"$slice":-2}}).pretty();
範例七:查詢返回年齡為19所有學生信息中只顯示參加的中間兩門課程,即第二和第三門課程------$slice
db.students.find({"age":19},{"course":{"$slice":[1,2]}}).pretty();-----跳過1個最多顯示2個,可以只顯示1個
說明:"$slice":[1,2]----第一個數值1表示跳過幾個數據,這裏為1就是跳過一個數據,從第二個開始顯示,顯示第二個和第三個

4.2.7嵌套運算------$elemMatch
在MongoDB中每一個幾乎數據可以繼續保存其他的集合數據,例如有些學生需要保存家長信息;範例:添加數據
db.students.insert({"name":"李白-F","sex":"男","age":24,"score":60,"address":"深圳","course":["語文","政治"],"parents":[{"name":"李白媽媽","age":33,"gender":"女","job":"局長"},{"name":"李白爸爸","age":29,"gender":"男"}]});
查看語句,查看職位為局長的人,且是parents,年齡大於19歲的
db.students.find({"$and":[{"$age":{"$gte":19}},{"parents":{"$elemMatch":{"job":"局長"}}}]}).pretty();

4.2.8判斷某個字段是否存在
使用"$exists"可以判斷某個字段是否存在,如果設置為true表示存在,如果設置為false表示不存在;
範例:查詢具有parents成員的數據
db.students.find({"parents":{"$exists":true}}).pretty();
範例:查詢無course成員數據
db.students.find({"course":{"$exists":false}}).pretty();
可以利用這種方法來進行無需信息的過濾
4.2.9條件過濾---$where
範例一:查詢年齡大於20的學員
db.students.find({"$where":"this.age>20"}).pretty();
db.students.find({"this.age>20"}).pretty();
上面這種方法是對數據庫中每一行數據進行判斷,在數據量大的時候不建議使用這種方式
可以使用js函數進行查詢
db.students.find(function(){return this.age>20;}).pretty();
db.students.find({"$where":function(){return this.age>20;}}).pretty();
上面是只有一個判斷條件,如果有多個判斷條件可使用and連接
例如查詢年齡在19到21之間的,這樣查詢出來的只有20
db.students.find({"$and":[{"$where":"this.age>19"},{"$where":"this.age<21"}]}).pretty();
雖然這種形式的操作可以實現數據查詢,但是最大缺點是將MongoDB裏面保存的BSON數據變為了JavaScript的語法結構,這樣的方式不方便使用數據庫索引機制。
4.2.10正則運算
如果想實現模糊查詢,則必須使用正則表達式,而且正則表達式使用的是語言Perl兼容的正則表達式形式,使用正則表達式方法如下:
基礎語法:{key:正則標記};
完整語法:{key:{"$regex":正則標記,"$options":選項}}
options在設置正則信息查詢時標記如下:
i:忽略字母大小寫
m:多行查找
x:空白字符串出了唄轉義的或在字符類中意外的完全忽略
s:匹配所有字符,包括換行內容;
註意點:如果直接使用(JavaScript)則只能使用i和m
而"x"和"s"必須使用"$regex"
範例:查詢以"鐵"開頭的學員信息
db.students.find({"name":/鐵/}).pretty();-----這裏的鐵不可加引號,加上引號就是字符串了
範例二:查詢名字中含有字母A的
db.students.find({"name":/a/i}).pretty();-----這裏的i就是不區分大小寫
說明:如果只需要執行模糊查詢操作,嚴格講只需要像上面這樣編寫一個關鍵字就可以了;
完整格式寫法:
db.students.find({"name":{"$regex":/a/i}}).pretty();
正則操作之中除了可以查詢出單個字段內容之外,還可以進行數組的查詢。
範例:查詢course中帶有"語"的內容
db.students.find({"course":{"$regex":/語/}}).pretty();
MongoDB中的正則符合和之前使用的JavaScript等正則有一些差別,這裏只用在模糊查詢就好了,最好不要用更多的正則表達式;

MongoDB學習記錄一