一、MongoDB介紹
1、NoSQL:非關系型數據庫
在php的世界里,常見的非關系型數據庫有memcached、redis、mongodb
2、MongoDB介紹
mongodb是針對海量數據開發的持久化類型NoSQL,直接把數據存儲到硬盤。mongodb主要是存儲日志或者報表之類的數據。這類數據的量都是非常大的,并且缺失少許數據是無關緊要的。
mongodb語法與js相同,并且可以在mongodb里面寫js代碼,以完成特定功能。
mongodb 有庫的概念,庫的下面是集合(表)的概念,集合的里面是文檔(數據)的概念。
數據以文檔的方式來體現的,一行行的文檔都是插入的數據。
mongodb的id默認帶主鍵索引。主鍵索引是不能修改、不能刪除,并且是必須存在,值是不可重復的。
3、MongoDB的安裝與配置
安裝
在linux中得到壓縮包解壓完成并進入目錄,發現里面的內容,可以直接使用,所以直接把解壓文件夾移動到/working
目錄下即可。
mv mongodb-linux-i686-3.2.15/ /working/mongodb
在mongodb文件夾里,mongod是服務器。
多數情況下,linux中的軟件在取名時,文件名末尾有d的代表服務器,沒有d的代表客戶端
查看幫助信息
/working/mongodb/bin/mongod --help
參數:
默認端口號:27017
--logpath arg:這里的"arg"是文件,不能寫目錄
--logappend:追加寫日志
--fork:后臺運行
--auth:運行的時候,要用戶驗證
--storageEngline arg:默認引擎:wiredTiger;但是64位支持的。32位不支持;3.0之后的32位默認引擎要修改成mmapv1
--dbpath arg:指定一個目錄
配置參數:
--port 27017
--logpath 創建一個目錄:logs目錄
--dbpath 創建一個目錄:data目錄
啟動mongodb服務器
/working/mongodb/bin/mongod --port 27017 --fork --logpath /working/mongodb/logs/mongod.log --logappend --storageEngine mmapv1 --dbpath /working/mongodb/data/
啟動之后檢查一下有沒有端口號和進程號
啟動客戶端
/working/mongodb/bin/mongo 192.168.xxx.xx:27017
4、快速入門
(1)數據庫(db)
查看庫:show databases;
或者show dbs
進入庫:use db_name
說明:mongodb默認是可以進入任意一個庫的。這個庫存在不存在都可以。進入不存在的庫,只有在庫里面有數據了,就會自動創建這個庫。
(2)集合(collection)
查看集合:show tables;
查看集合:show collections
默認情況下,當你的集合下面有數據的時候,就會自動創建這個集合 。
(3)文檔(document):插入數據
插入數據: db.collection_name.insert({});
db :表示當前庫
collection_name:集合名稱
insert:操作動作(插入)
{} :文檔,要寫入的數據,數據格式是json。
eg:db.book.insert({name:"xiaoming", age:18, sex:2});
查看數據:db.collection_name.find();
eg:db.book.find();
插入數據的時候,沒有指定id,會默認的生成一個id的字符串!
手動插入id:id的字段名必須是_id
值必須是不重復 ; db.collection_name.insert({_id:1})
eg:db.book.insert({_id:1,name:"xiaohong",age:19,sex:1});
插入多條數據:db.collection_name.insert([{},{}]);
。[{},{}] 。每一個文檔,就是一條數據!
eg:db.book.insert([{_id:2,name'xiao2',age:19,sex:1},{_id:3,name:'xiao3',age:19,sex:2}]);
使用js自動生成數據:
function autoinsert(){ for(var i = 10; i < 20; i++){ db.book.insert({_id:i, name:"xiao" + i, age: i + 10, sex:1}); } } //執行這個函數 autoinsert(); //查看數據 db.book.find();
(4)文檔(document):更新數據、刪除數據
更新數據:db.collection_name.update({},{});
db :表示當前庫
collection_name:集合名稱
update:操作動作(更新)
{}:第一個文檔,更新條件
{}:第二個文檔,更新的值
eg:db.book.update({name:"xiaohong"}, {age:10});
注:此用法,在更新之后,只保留更新的值與ID,其它的字段都不在了,因此使用下面的方法
選擇器:
$set:只修改更新的內容,其它值保持不變
$inc:數值型值,指定自增多少,或者自減多少
db.collection_name.update({},{});
{}:第一個文檔,更新條件
{}:第二個文檔,更新的值。第二個文檔的內容寫法:$set:{更新的內容}
eg:
db.book.update({name:"xiaoming"},{$set:{age:10}});
指定自增:$inc
db.book.update({_id:2}, {$inc:{age:1}});
指定直減:$inc
db.book.update({_id:11}, {$inc:{age:-1}});
修改內容的數量:$set
db.book.update({age:20}, {$set:{sex:2}});
mongodb是一個海量的數據庫,默認只是更新匹配到的第一個值!
更新數據的量,第三個文檔:db.collection_name.update({},{},{});
{}:第三個文檔里面可以有二個值
? multi:true 。true值,表示滿足匹配條件的數據,全部更新;false(默認)值,表示更新第一條匹配到的數據。
? upsert:true 。true值,表示沒有匹配到任何數據,轉成插入該數據;false(默認)值,表示沒有匹配到任何數據,放棄操作。與MySQL里面的replace語法效果相同。
更新全部匹配的值:multi:true
eg:db.book.update({age:20},{$set:{sex:3}},{multi:true});
更新數據的時候,沒有匹配的值,插入該數據:upsert:true
eg:db.book.update({age:18},{$set:{sex:2}},{upsert:true});
upsert與multi是可以同時使用的!
db.book.update({age:20}, {$set:{sex:2}},{upsert:true,multi:true});
刪除數據:db.conllection_name.remove({});
db :表示當前庫
collection_name:集合名稱
remove:操作動作(刪除)
{}:第一個文檔,刪除條件;空文檔,匹配全部數據
eg:db.book.remove({age:18});
刪除數據的時候,默認是匹配到多少,刪除多少。
刪除數據的量,第二個文檔:db.conllection_name.remove({},{});
{}:第二個文檔里面可以有一個值
? justOne:true 。true值,表示滿足匹配條件的數據,刪除一條;false(默認)值,表示匹配到的數據,全部刪除。
eg:db.book.remove({age:20},{justOne:true});
刪除空文檔的效果:db.book.remove({});
,此時的數據就全部刪除了
(5)刪除collection與刪除db
刪除集合:db.collection_name.drop();
eg:db.book.drop();
刪除數據庫:db.dropDatabase();
重點強調:要刪除哪一庫,必須在這個庫里面操作!
(6)瞬間完成
上面的插入,刪除和更新操作都是瞬間完成的,它們不需要等待數據庫響應。這樣的實現可以獲取高性能,速度非常快,只會受客戶端發送速度和網絡速度的制約。但由于不會獲取服務器狀態,所以不能保證操作順利完成。這對于付費系統,安全性較高的系統是不可行的,此時對這些操作需要使用它們的安全版本。安全版本會在操作執行后立即運行getLastError命令,來檢查是否執行成功。如果失敗一般會拋出可捕獲的異常,然后我們可以在代碼中處理。
5、MongoDB進階
(1)MongoDB幫助系統
系統幫助:help
help后面不要加分號[;]
庫幫助:db.help();
集合幫助:db.collection_name.help();
操作動作幫助:db.collection_name.find().help();
mongodb的幫助信息,非常的方便,可以直接實現。
(2)查詢
$eq(等于);$ne(不等于); $lt(小于);$lte(小于等于);$gt(大于);$gte(大于等于);$in(包含);$nin(不包含);$and(并且);$or(或者)
- 等于:
db.collection_name.find({name:{$eq:'xiao0'}});
- eg:
db.book.find({name:{$eq:"xiao0"}});
- eg:
- 不等于:
db.collection_name.find({name:{$ne:'xiao0'}});
- eg:
db.book.find({name:{$ne:"xiao0"}});
- eg:
- 小于:
db.collection_name.find({age:{$lt:14}});
- eg:
db.book.find({age:{$lt:14}});
- eg:
- 小于等于:
db.collection_name.find({age:{$lte:14}});
- eg:
db.book.find({age:{$lte:14}});
- eg:
- 大于:
db.collection_name.find({age:{$gt:14}});
- eg:
db.book.find({age:{$gt:14}}); ";
- eg:
- 大于等于:
db.collection_name.find({age:{$gte:14}}) ;
- eg:
db.book.find({age:{$gte:14}});
- eg:
總結:$eq $ne $lt $lte $gt $gte
db.collection_name.find({field:{$eq:value}})
- 包含:$in;
db.collection_name.find({field:{$in:[value,value]}});
- eg:
db.book.find({age:{$in:[13,14,15]}});
- 不包含:$nin;
db.collection_name.find({field:{$nin:[value,value,value]}});
- eg:
db.book.find({age:{$nin:[13,14,15]}});
總結:$in $nin
db.collection_name.find({field:{$in:[v,v,v]}});
- 并且:$and
db.collection_name.find({$and:[{age:1},{name:”xiao1”}]});
- eg1:
db.book.find({$and:[{name:"xiao0"},{age:10}]});
- eg2:
db.book.find({$and:[{name:"xiao0"}, {age:{$lt:11}}]});
- 或者:$or
db.collection_name.find({$or:[{field:value},{field:value}]});
- eg:
db.book.find({$or:[{name:"xiao0"},{age:{$gt:18}}]});
總結:$and $or
db.collection_name.find({$and:[{field:value},{field:value}]});
查詢條件說明:
操作動作find示例,演示了匹配條件。其它的操作動作只要有匹配條件的,都可以使用這些匹配條件。
例如,操作動作update(更新)的第一個文檔,就是匹配條件,這些就可以完全被使用。
例如,操作動作remove(刪除)的第一個文檔,就是匹配條件,這些就可以完全被使用。
查詢動作(find)的過濾動作介紹:
- 內容跳過:skip
db.book.find().skip(2);
skip(n) :number是一個整型。
- 內容顯示:limit
db.book.find().limit(2);
limit(n):number是一個整型 。
- 內容統計:count
db.book.find().count();
- 內容統計:size
db.book.find().size();
- 內容排序:sort
field:value
value === 1 :升序;
db.book.find().sort({name:1});
value === -1 :降序;
db.book.find().sort({name:-1});
- 實現分頁效果:skip與limit
db.book.find().skip(2).limit(2);
count默認是不認可skip與limit的操作的。
- 使用skip或者limit的時候:
db.book.find().skip(8).limit(2).count(true);
- 約束返回數據:
db.collection_name.find({},{});
{}:第二個文檔,表明返回哪些字段的數據。
_id:value 。0值,不返回;1值,返回
設置注意:
同時設置_id與其它字段時。_id是要返回,其它字段必須是返回;_id是不返回,其它字段可以返回或者不返回。
設置多個其它字段時,其它字段的設置狀態必須保持一致。
db.book.find({},{_id:1});
_id如果返回,其它字段也必須返回;
_id如果不返回,其它字段可以返回或者不返回:
db.book.find({},{_id:0, name:1,age:1});
,此時就是返回的字段是:name,age
設置多個其它字段時,其它字段的設置狀態必須保持一致:
db.book.find({},{_id:0, name:0,age:0});
下面是錯誤寫法:
db.book.find({},{_id:0, name:0,age:1});
- 整型與字符:
db.book.insert({_id:10,name:"xiao10",age:"19",sex:1});
- 查看age是19的:
db.book.find({age:19});
說明:mongodb里面,是區分字符數字與整型的。
- 集合下的統計:count
db.book.count({_id:{$gt:15}});
在Mongodb里面有很多方法實現相同的效果,掌握一種就可以了 。
(3)聚合
db.collection_name.aggregate({});
{}:文檔里面可以有三個值
$match:{}
? {} 這個文檔里面的值,同find的查找內容別無二致。
$group:{}
? {} 這個文檔里面的值,非常重要。
? _id :這個是必須寫的,強制要求的,文檔有強調。
例:
{_id:'123'};
給每一行文檔一個固定的值是123,對文檔的123值進行分組。分組結果:_id是字段,值是123。
{_id:"$sex"};
對每一行文檔里面的sex字段值進行分組。分組結果:_id是字段,值是sex字段不重復的值。
{_id:"$sex", fieldname:{$sum:1}};
給每一行文檔一個固定的值是1。對每一行文檔里面的sex字段值進行分組,統計每一個分組里面固定值1的和(sum),并且把和的結果給字段fieldname。分組結果:_id是字段,值是sex不重復的值;fieldname是字段,值是統計固定值1的結果。
{_id:"$sex", fieldname {$sum: "$age"}}
對每一行文檔里面的age字段值進行分組,統計每一個分組里面sex值的和(sum),并且把和的結果給字段fieldname。分組結果:_id是字段,值是age不重復的值;fieldname是字段,值是統計sex值的結果。
$sum :求和;$avg :求平均值;$max :求最大值;$min:求最小值。
$sort:{}
{}這個文檔里面的值,同find的排序動作(sort)別無二致。 age:1 。值1,升序;值-1,降序
-
$match;
db.quan6.aggregate({$match:{_id:{$lt:5}}});
eg:
db.book.aggregate({$match:{_id:{$lt:5}}});
-
$group
- eg1:
db.book.aggregate({$group:{_id:123}});
- eg2:
db.book.aggregate({$group:{_id:"$sex",persions:{$sum:1}}});
- eg3:
db.book.aggregate({$group:{_id:"$sex",persions:{$sum:"$age"}}});
- eg1:
統計所有人年齡的平均值:
db.school.aggregate({$group:{_id:1,avg:{$avg:"$age"}}});
統計不同性別的年齡的平均值:
db.school.aggregate({$group:{_id:"$sex",avg:{$avg:"$age"}}});
統計所有人的年齡的最大值:
ab.school.aggregate({$group:{_id:1,man:{$min:"$age"}}});
- $sort
- 升序:
db.school.aggregate({$sort:{sex:1}});
- 降序:
db.school.aggregate({$sort:{sex:-1}});
- 升序:
三大值都單詞操作完成了:組合使用!
db.collection_name.aggregate([{},{},{}]);
三個大的類型,可以寫一個,寫二個,或者寫三個。
$match與$group
db.school.aggregate({$match:{_id:{$lt:8}}},{$group:{_id:"$sex",avg:{$avg:"$_id"}}});
$match與$sort
db.school.aggregate({$match:{_id:{$lt:8}}},{$sort:{age:-1}});
$group與$sort
db.school.aggregate({$group:{_id:"$sex", agemax:{$max:"$age"}}},{$sort:{agemax:1}});
發現:2個一起使用時,第一個結果就是第二個的參數
三個連用:
db.school.aggregate([{$match:{_id:{$ne:10}}},{$group:{_id:"$sex",agesum:{$sum:"$age"}}},{$sort:{_id:1}}]);
最好的使用順序就是match然后是group再是sort
(4)mapReduce:批量操作
db.collection_name.mapReduce(map, reduce, {});
map:函數名稱。
掃描集合中的所有文檔,把每一行文檔的數據拿來處理。每一行文檔數據,都執行一次map函數。
執行map函數,this表示正在執行的這行文檔對象。使用某一個字段,就使用this.field。
例如:獲取年齡(this.age)
函數執行完成,想要存儲結果,必須調用內置emit函數。
該函數必須有二個參數:emit(v1, v2)。
function map(){ emit(this.sex, this.age) }
假如:文檔數量有4個!map實現是emit(this.sex, this.age)
掃描第一行文檔的時候,產生的結果:array(sex => array(age))
掃描第二行文檔的時候,產生的結果:array(sex => array(age, age))
掃描第三行文檔的時候,產生的結果:array(sex => array(age, age, age))
掃描第四行文檔的時候,sex和上面的三個不一樣了,產生的結果:
? array(sex => array(age, age, age), sex => array(age))
數值:(age : 10; sex :1); (age:11; sex:1); age: 12; sex:1); (age:13; sex:0)
emit(this.sex, this.age)
掃描第一行文檔的時候,產生的結果:array(1 => array(10))
掃描第二行文檔的時候,產生的結果:array(1 => array(10, 11))
掃描第三行文檔的時候,產生的結果:array(1 => array(10, 11, 12))
掃描第四行文檔的時候,產生的結果:array(1 => array(10, 11, 12), 0 => array(13))
reduce:函數名稱。該函數有二個參數(v1, v2)
? 第一個參數,是emit函數的key值
? 第二個參數,是emit函數的value值(數組)
reduce函數調用的次數,由emit函數存儲的key數量決定。emit函數有二個key,reduce函數就調用二次。
reduce函數,就是去循環emit函數的結果
{}:文檔。設置不同作用的值一個
? out:{inline:1} 。打印到屏幕
? out:{replace:”collection_name”} 。結果存儲到collection_name集合里面
collection_name集合存在就覆蓋,不存在就創建!
實現map函數:
獲得sex與age,存儲起來
function map(){
var age = this.age;
var sex = this.sex;
emit(sex,age);
}
實現reduce函數:
求的不同性別年齡的和!
function reduce(sex, ages){
var agesum = Array.sum(ages);
var res = sex + '-' + agesum;
return res;
}
實踐:
db.quan6.mapReduce(map,reduce,{out:{inline:1}});
(5)索引
- 查看索引:
db.collection_name.getIndexes();
- eg:
db.book.getIndexes();
- eg:
- 創建索引:
db.collection_name.createIndex({field:1});
field:1 。1值是升序索引;-1值是降序索引。
? eg:db.book.createIndex({age:1});
之所以寫索引名稱,就是方便管理
- 刪除索引:
db.collection_name.dropIndex(索引名);
- eg:
db.book.dropIndex('age_1');
- eg:
- 刪除主鍵索引:
db.book.dropIndex('_id_');
- 創建唯一索引:
db.collection_name.createIndex({field:1},{unique:true});
unique:true :是true的時候,才是唯一索引,強調在創建的時候,值必須是沒有重復的
? eg:db.book.createIndex({name:1},{unique:true});
- 測試唯一索引:
db.collection_name.insert({});
- eg:
db.book.insert({_id:10,name:"xiao9",age:19,sex:1});
- eg:
- 不使用重復的值:
db.book.insert({_id:10,name:"xiao10",age:19,sex:1});
- 查看索引被使用了:
db.collection_name.find({''}).explain('executionStats');
- eg:
db.book.find({name:"xiao9"}).explain('executionStats');
- eg:
- 創建一個降序索引:
db.collection_name.createIndex({field:-1});
- eg:
db.book.createIndex({age:-1});
- eg:
- 刪除全部索引,不包含主鍵索引:
db.collection_name.dropIndexes();
- eg:
db.book.reopIndexes();
- eg:
索引是為了海量數據準備的,所有有很多不一樣的特性。都是因為數據不一樣而產生的。mongodb還有很多種索引的類型。
(6)固定集合
就是提前創建好集合,并且設定它有大小。里面的數據,不能刪除。數據存儲滿了之后,使用最近最少原則刪除內容。
作用,當項目有一些數據,是前面的數據無用的。保持一定的數據量,就可以使用它。
db.createCollection('collection_name', {});
文檔的說明:
? capped:true 。true值的時候,表示是創建的固定集合。必須的值
? size:50 。設置集合的存儲空間大小。必須的值
max:3 。設置集合最大的文檔數量。可選的值
強調:max與size這二個限制大小的操作,任何一個先到達,就開始執行最近最少使用原則刪除數據。
- 創建一個:
db.createCollection('python',{capped:true,size:50,max:3});
- 查看集合:
show tables;
- 插入數據:
db.python.insert({_id:1,name:"xiao1",age:12});
- 查看數據:
db.python.find();
- 更新數據:
db.python.update({_id:2},{$set:{age:22}});
- 刪除數據:
db.python.remove({_id:5});
- 刪除集合:
db/python.drop();
固定集合,是可以刪除的。但是里面的數據是不能刪除的。只能插入與更新。
(7)GridFS功能
就是把文件以二進制的形式,上傳到mongodb里面存儲的。獲取出來的時候,直接轉換成了曾經的模式。
①找到工具:在目錄/working/mongodb/bin
下的mongofiles
文件。
它可以把任何文件上傳到mongodb里面。無論是圖片,還是壓縮文件,還是文本文件。都可以以二進制的形式,存儲到mongodb的數據庫里面。
mongodb會以2G的空間大小,劃分出區域來存儲這些內容。這個時候,2G來劃分,就很難產生硬盤的碎片!對搜索數據就會有性能的提升。
②查看幫助信息并確定參數:/wordking/mongodb/bin/mongofiles --help
確定參數:
list:顯示;search:查詢;put:上傳;get:下載;delete:刪除
上傳與下載的時候,指定文件路徑。
③上傳文件:/working/mongodb/bin/mongofiles --db=data put install --local=/root/install.log.syslog
顯示一下:/working/mongodb/bin/mongofiles list --db=data
④下載文件:/working/mongodb/bin/mongofiles get install --local=/home/install.log --db=data
⑤搜索:/working/mongodb/bin/mongofiles search a --db=data
自帶模糊匹配
刪除:/working/mongodb/bin/mongofiles delete apr --db=data
6、MongoDB的用戶管理
(1)MongoDB中的權限角色
角色:
收銀員(虛擬):收錢,發錢。
? 權限是掛在角色上面。
李白:擁有收銀員的角色
? 權限:收錢,發錢。
? 用戶是要有角色的,通過角色就有相應的權限。
mongodb里面是使用的這種權限。還是有其它權限管理的。
mongodb里面默認的角色:
庫的角色:
read :讀的權限
readWrite :讀寫的權限
userAdmin :管理庫的權限
集群的角色:
readAnyDatabase :集群的讀的權限
readWriteAnyDatabase :集群的讀寫的權限
userAdminAnyDatabase :集群的管理庫的權限
管理員:root
mongodb里面有很多已經設定好的角色,太多了,需要的在看
(2)開啟MongoDB中的權限控制
啟動mongodb服務器的時候,加上參--auth就可以了。開啟之后,登錄mongodb服務器,就必須要使用賬戶與密碼。
注意:在開啟賬戶與密碼的時候,一定一定要提前設置好有管理員的權限(至少)。
提前設置好:集群的管理庫的權限
db.createUser({
user:'username',
pwd:'password',
roles:[{role:'rolename', db:'管理的庫'}]
})
重點介紹:mongodb里面用戶是屬于某一個庫的。必須在這個庫里面才能使用這個用戶。
創建管理員:
注意,必須先進入admin這個庫。這個庫曾經是管理員的庫,然后現在默認是自己創建用戶的時候,才生成。以前是自帶的。所有現在創建第一個管理員,保持和曾經一樣,先進入這個庫。在這里創建一個管理員。
1)進入admin庫
use admin
2)創建一個管理員
db.createUser({
user:"zhang",
pwd:"123456",
roles:[{role:"userAdnubAnyDatabase", db:"admin"}] //權限是集群的管理庫的,屬于admin庫
})
3)查看當前庫
show collections
查看數據:db.system.indexes.find();
,這個就是索引。
查看創建用戶名信息:db.system.users.find();
4)客戶端退出
exit
5)停止服務器
先查看進程,通過進程來關閉!ps aux | grep mongod
使用kill 的時候,注意,一定不要使用-9來關閉。因為mongodb里面的官方文檔說的,不要使用。
如果你使用了-9,有可能就啟動不起來了。如果你啟動不起來了。就查看一下目錄:
/working/mongodb/data
,刪除data目錄下面的mongod.lock即可。
6)啟動服務器,加上—auth參數
/working/mongodb/bin/mongod --port 27017 --fork --logpath /working/mongodb/logs/mongod.log --logappend --storageEngine mmapv1 --dbpath /working/mongodb/data/ --auth
7)使用客戶端登錄:
/working/mongodb/bin.mongo 192.168.xxx.xx:27017
此時登錄成功后如果要show dbs
時,如果發現報錯了,這是因為沒有權限。
用戶是屬于庫的,所以我們要進入用戶所在的庫,進行登錄。
選擇use admin
庫后,再進行登錄:db.auth('zhang','123456');
,顯示1,則是登錄成功。再查看當前庫:show collections;
,此時也會報錯,'zhang'是管理員,沒有查看的權限。
8)使用管理員,創建一個用戶。
db.createUser({
user:"adminr",
pwd:"123456",
roles:[{role:"read",db:"admin"}] //權限為讀,用戶屬于admin這個庫
})
使用這個新的用戶:use admin
選擇庫后,進行登錄:db.auth("adminr","123456");
,查看庫:show tables;
,是可以查看的,但是繼續查看db.system.users.find();
時又會報錯,還是沒有權限。
9)進入到管理員
use admin
,并且登錄db.auth('zhang','123456');
10)給quan庫里面撞見一個readWrite的用戶
use quan
db.createUser({
user:"quanrw",
pwd:'123456',
roles:[{roles:"readWrite", db:"quan"}]
})
使用這個賬戶:use quan
,登錄一下:db.auth('quanrw', '123456');
,查看庫:show tables;
,這個庫里沒有東西,但是可以往里面寫內容:db.quan.insert({_id:1, name:"123"});
,使用一下讀操作:db.quan.find();
即可讀出數據。
7、使用PHP操作MongoDB
(1)安裝php_mongo擴展
給php安裝mongodb的擴展,讓php成為可以連接mongodb服務器的客戶端!
http://pecl.php.net/package-search.php?pkg_name=mongo&bool=AND&submit=Search
mongo有2個擴展,任意選擇一個都可以。但是mongo擴展只能是php7以下的,mongodb擴展支持7以上的。
安裝linux擴展:
得到擴展的壓縮包,放到linux下,解壓:tar -zxf /存放路徑/mongodb-1.3.4.tgz
進入到該目錄下,再確定好PHP版本后安裝mongodb擴展, 我們要給這個安。就要使用里面的phpize與php-config這2個程序。只能是這個版本的,不能混用 。
編譯安裝:./configure --with-php-config=/working/php7/bin/php-config && make && make install
安裝完成后查看擴展,在目錄:/working/php7/lib/php/extensions/no-debug-zts-20160303/
下,會有一個mongodb.so
文件。
配置php.ini信息:vim /working/php7/etc/php.ini
打開的這個php.ini配置文件,肯定是和phpize與php-config同一個版本下面的。
進入文件后,在大概929行左右,添加:extension=mongodb.so
驗證一下:/working/php7/bin/php -m
,如果出現mongodb時說明安裝成功。
(2)使用PHP連接MongoDB
mongodb擴展與mongo擴展,他們的操作方式是完全不一樣的。
你使用哪一個擴展,就使用哪一個擴展的說明文檔,進行操作。
$manager = new MongoDB\Driver\Manager("mongodb://quanrw:123456@192.168.xxx.xx:27017/quan");
var_dump($manager);
如果配置信息沒有錯誤,可以打印出相關的對象信息。
(3)使用PHP+MongoDB實現CURD操作
$insert = new MongoDB\Driver\BulkWrite;
$insert -> insert(['_id' => 1, 'name' => 'xiao1', 'age' => 10, 'sex' => 1]);
$insert -> insert(['_id' => 2, 'name' => 'xiao2', 'age' => 10, 'sex' => 1]);
$insert -> insert(['_id' => 3, 'name' => 'xiao3', 'age' => 10, 'sex' => 2]);
$insert -> insert(['_id' => 4, 'name' => 'xiao4', 'age' => 10, 'sex' => 2]);
$manager = new MongoDB\Driver\Manager("mongodb://quanrw:123456@192.168.xxx.xx:27017/quan");
$manager -> executeBulkWrite('quan.quan6', $insert);
var_dump($manager);
訪問頁面后可以看到打印出的數據信息,可以再進入數據庫驗證數據:
show tables;
db.quan6.find();
更新數據:
$update = new MongoDB\Driver\BulkWrite;
//mongodb寫的時候,一定要寫單引號
$update -> update(['sex' => ['$eq' => 1]], ['$set' => ['age' => 11]], ['multi' => true, 'upsert' => true]);
//連接mongodb數據庫
$manager = new MongoDB\Driver\Manager("mongodb://quanrw:123456@192.168.xxx.xx:27017/quan");
//執行構建
$manager -> executeBulkWrite('quan.quan6', $update);
var_dump($manager);
刪除數據:
$delete = new MongoDB\Driver\BulkWrite;
//在php里面limit是真的時候,表示刪除一條數據
$delete -> delete(['age' => 10], ['limit' => 1]);
//連接mongodb數據庫
$manager = new MongoDB\Driver\Manager("mongodb://quanrw:123456@192.168.xxx.xx:27017/quan");
//執行構建
$res = $manager -> executeBulkWrite('quan.quan6', $delete);
var_dump($res);
查詢數據:
//查詢條件
$filter = ['_id' => ['$in' => [1, 2, 4]]];
//過濾選擇
$options = [
//查詢想要的字段:字段值如果對應的是0,不顯示。對應的值是1,就是顯示
'projection' => ['_id' => 0, 'name' => 1, 'age' => 1],
'sort' => ['age' => 1],
'skip' => 1,
'limit' => 1,
];
$query = new MongoDB\Driver\Query($filter, $options);
//連接MongoDB服務器
$manager = new MongoDB\Driver\Manager("mongodb://quanrw:123456@192.168.xxx.xx:27017/quan");
$cursor = $manager -> executeBulkWrite('quan.quan6', $query);
foreach($cursor as $value)
{
var_dump($value);
echo '<br>';
}
聚合:
//聚合使用
$options = [
//aggregate表示聚合,對應的是聚合名稱
'aggregate' => 'quan6',
'pipeline' => [
['$match' => ['_id' => ['$in' => [1, 2, 4]]]],
['$group' => ['_id' => '$sex', 'agesum' => ['$sum' => '$age']]],
['$sort' => ['agesum' => 1]],
],
'cursor' => new stdClass,
];
//構架聚合
$command = new MongoDB\Driver\Command($options);
//連接MongoDB服務器
$manager = new MongoDB\Driver\Manager("mongodb://quanrw:123456@192.168.xxx.xx:27017/quan");
//執行構建
$cursor = $manager -> executeBulkWrite('quan', $command);
foreach($cursor as $val)
{
var_dump($val);
echo '<br>';
}