最近在自學MongoDB,在此記錄一下,當作學習筆記了(不斷更新中)!!sql
1、背景mongodb
MongoDB 是一個基於分佈式文件存儲的數據庫。由 C++ 語言編寫。旨在爲 WEB 應用提供可擴展的高性能數據存儲解決方案。它是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。MongoDB 將數據存儲爲一個文檔,數據結構由鍵值(key=>value)對組成。MongoDB 文檔相似於 JSON 對象。字段值能夠包含其餘文檔,數組及文檔數組。數據庫
其放棄關係模型的緣由就是爲了得到更加方便的擴展、穩定容錯等特性。面向文檔的基本思路就是:將關係模型中的「行」的概念換成「文檔(document)」模型。面向文檔的模型能夠將文檔和數組內嵌到文檔中。所以,實際中能夠用一條數據表示很是複雜的結構。MongoDB沒有預約義模式:文檔的鍵(key)和值(value)再也不是固定的類型和大小,並且根據需求要添加或者刪除字段變得更容易了。數組
實際應用中,隨着數據量的增大,數據庫都要進行擴展。擴展有縱向擴展和橫向擴展。縱向擴展是使用計算能力更強的機器,也是最省力的方法,可是很容易達到物理極限,不管花多少錢也買不到最新的機器了。橫向擴展就是經過分區將數據分散到更多的機器上。MongoDB的設計採用橫向擴展。面向文檔的數據模型使它很容易地在多臺服務器之間進行數據分割。還能夠自動處理跨集羣的數據和負載,自動從新分配文檔,以及將用戶請求路由到正確的機器上。開發者根本不用考慮數據庫層次的擴展問題,須要擴展數據庫時,在集羣中添加機器便可,MongoDB會自動處理後續的事情。 服務器
3、MongoDB數據類型數據結構
4、經常使用命令架構
1) db:查看當前的數據庫;編輯器
2) show dbs:顯示全部數據庫列表;分佈式
3) db.stats():查看數據庫狀態;性能
4) use:切換到某個數據庫;
5) db.dropDatabase():刪除數據庫(須要先切換到對應的數據庫);(用的時候本身建立)
6) db.createCollection(name, options):建立集合;(用的時候本身建立)
7) db.${collection}.drop():刪除集合;
8) db.${collection}.insert():插入文檔;
9) db.${collection}.save():插入文檔;
10) db.${collection}.findOne():查看一篇文檔;
11) db.${collection}.find().pretty():以更加友好的方式查看已插入文檔;
12) db.collection.update():更新文檔;
13) db.collection.remove():刪除文檔;可是並不會釋放存儲空間,需執行db.repairDatabase() 來回收磁盤空間。推薦deleteOne(),deleteMany();
14) db.${collection}.deleteMany({}):刪除所有文檔
15) db.${collection}.deleteOne({}):刪除符合條件的一個文檔
16) db.${collection}.find().limit(${num}):讀取指定數量的數據記錄;
17) db.${collection}.find().limit(${num1}).skip(${num2}):跳過指定數量的數據
18) db.${collection}.find().sort({${key}:1/-1}):排序,1升序,-1降序
19) db.${collection}.createIndex():建立索引
20) db. ${collection}.help(); #查詢對相應表的一些操做
21) db.mycoll.find().help(); #查詢的方法,排序,最大最小等...
5、插入
mongoDB中插入數據有insert()與save()兩個命令,兩者的聯繫是:
1) 對於數據庫中沒有改字段,二者沒有區別;
2) 對於數據庫中有該字段,insert會報錯,save會執行更新操做
3) 若新增的數據中存在主鍵 ,insert() 會提示錯誤,而save() 則更改原來的內容爲新內容。
save()
db.student.save({_id:1,classid:1,age:18,name:"little1",love:["football","swing","cmpgame"]});
db.student.save({_id:2,classid:2,age:19,name:"little2",love:["play"]});
db.student.save({_id:3,classid:2,age:20,name:"little3"});
db.student.save({_id:4,classid:1,age:21,name:"little4"});
db.student.save({_id:5,classid:1,age:22,name:"little5",opt:"woshisheia"});
db.student.save({_id:6,classid:2,age:23,name:"23little4"});
insert():int類型賦值不要加引號,字符串賦值要加引號,單引號和雙引號均可以,推薦使用單引號,由於雙引號在一些編輯器中轉義會有一些問題
1)插入普通數據命令: db.goods.insert({name:'xiaomi',price:2000,number:'50'})
2)插入具備對象數據命令:db.goods.insert({name:'xiaomi',price:2000,number:'50',area:{province:'jiangsu',city:'nanjing'}})
3)插入數組數據命令: db.goods.insert({name:'xiaomi',price:2000,number:'50',area:{province:'jiangsu',city:'nanjing'},color:['black','red','greed']})
4)批量插入數據:for (i=0;i<1000;i++) db.tables1.insert({name:"Alex"+i});
6、查詢
1)find({${where條件},${0屬性不顯示 /1屬性顯示}}):查詢,若是where條件沒有,那就用{}表示,不能省略。而顯示與否的{}能夠省略的。
db.student.find();
//查詢 name爲little1的學生,而且只顯示 age,name兩個字段
db.student.find({name:"little1"},{name:1,age:1}) 等價於 select name,age from student where name = "little1"
//and:查詢 name爲little1,age爲18的學生,而且只顯示 age,name,love三個字段
db.student.find({name:"little1",age:18},{name:1,age:1,love:1}) 等價於 select name,age,love from student where name = "little1" and age = 18
//$or:查詢 name爲little3或age爲19的學生
db.student.find({'$or':[{name:'little3'},{age:19}]}) 等價於 select * from student where name = "little3" or age = 19
db.student.find({'$or':[{name:'little3'},{age:19}]},{name,1})
2)findOne({${where條件},${0屬性不顯示 /1屬性顯示}}):查詢,只返回第一個
db.student.findOne().pretty(); 這裏的pretty()是將結果格式化,find() 與 findOne() 後面均可以使用
3)skip(num): 參數num表示跳過的記錄條數,默認值爲0。 limit(num): 參數num表示要獲取文檔的條數,若是沒有指定參數則顯示集合中的全部文檔。skip() 與 limit() 不分前後順序 ,從第二條查尋,查出三條
db.student.find().skip(1).limit(3);
4)比較運算符號
//查詢出19<age<=21的數據
db.student.find({age:{$gt:19,$lte:21}});
//查詢age>20的數據
db.student.find({age:{$gt:20}});
db.student.find({$where:"this.age>20"});
db.student.find("this.age>20");
var f = function(){return this.age>20};
db.student.find(f);
5)$mod:查詢出age爲奇數的數據(對2求餘爲1即爲奇數)(這裏請注意[2,1]的位置不能錯)。
db.student.find({age:{$mod:[2,1]}}); 也可寫做:
6)$exists:查詢出存在opt字段的數據, 存在true,不存在false
db.student.find({opt:{$exists:true}}); db.student.find({opt:{$exists:false}});
7)查詢出name不爲little2的數據
db.student.find({name:{$ne:"little2"}});
8)$in:查詢出age爲16,18,19的數據
db.student.find({age:{$in:[16,18,19]}});
9)$nin:查詢出age不爲16,18,19的數據
db.student.find({age:{$nin:[16,18,19]}});
10)$size:查詢出love有三個的數據
db.student.find({love:{$size:3}});
11)查詢出name不是以litt開頭的數據
db.student.find({name:{$not:/^litt.*/}});
12)sort:1升序, -1降序
按age升序:db.student.find().sort({age:1}); 按age降序:db.student.find().sort({age:-1});
13)count:查詢數據條數。db.集合名稱.find({條件}).count() 或者 db.集合名稱.count({條件})
db.student.find().count(); 也能夠寫做db.student.count()
14)like:模糊查詢
db.student.find({name:/little/}); 至關於 select * from student where name like "%little%";
db.student.find({name:/^little/}); 至關於 select * from users where name like "little%";
15)distinct:去重。格式:db.集合名稱.distinct('去重字段',{條件})
db.student.distinct('name');
//查找年齡大於18的學生,來自哪些省份
db.stu.distinct('hometown',{age:{$gt:18}})
16)type:屬性類型判斷 常見的Double 是1,String是2,Boolean是8,Date是9,Null是10,32位int是16,Timestamp是17,64位int是18
db.sutdent.find({"title" : {$type : 2}}) db.student.find({"title" : {$type : 'string'}})
17)null:查詢age爲null的數據
db.student.find({age:null})
18)聚合(aggregate),主要用於計算數據,相似sql中的sum()、avg()
待補
7、更新
update() 方法用於更新已存在的文檔。語法格式以下:
db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document> } )
參數說明:
例:
db.person.insert([{"name":"chen","age":15},{"name":"li","age":20},{"name":"zhang","age":20}]);
用於修改鍵的值,若是鍵不存在就增長鍵
//將age=10的數據改爲15,默認若是age=10的有多條記錄只更新第一條
db.person.update({"name":"li"},{$set:{"age":10}})
//更新多個知足條件的值,同時若是更新的值不存在就插入更新的值,注意:這裏插入的值是20不是30
db.person.update({"age":30},{$set:{"age":20}},{multi:true,upsert:true})
能夠省略multi,upsert,這裏不能有花括號,可是不建議這樣作
db.person.update({"age":30},{$set:{"age":20}},true,true)
//值更新爲數組
db.person.update({"name":"zhang"},{$set:{"age":[10,12,14]}},{upsert:true})
//修改成其它的值
db.person.update({"name":"zhang"},{$set:{"age":''}},{upsert:true}) db.person.update({"name":"zhang"},{$set:{"age":null}},{upsert:true})
用於增長已有鍵的值,若是鍵不存在就建立,只能用於整形、長整型、浮點型。
//將name=zhang的記錄的age鍵+10
db.person.update({"name":"zhang"},{$inc:{"age":10}},{upsert:true})
//將name=zhang的記錄的age鍵-10
db.person.update({"name":"zhang"},{$inc:{"age":-10}},{upsert:true})
刪除鍵相似關係數據庫的刪除字段操做,要區別$set修改符的將鍵設空或者null值
db.person.update({"name":"zhang"},{$unset:{"age":1}})
注:有關數組更新操做的就不在這裏說明了!
8、刪除
1)刪除總體數據
db.goods.remove({name:xiaomi})
2 )刪除某條數據的某個字段
db.goods.remove({name:xiaomi},{'$unset':{name:1}}) 或 db.goods.remove({name:xiaomi},{'$unset':{name:0}})
注:
一、remove() 方法 並不會真正釋放空間。須要繼續執行 db.repairDatabase() 來回收磁盤空間。
二、remove() 方法已通過時了,如今官方推薦使用 deleteOne() :刪除符合條件的一條數據、 deleteMany()——刪除符合條件的多條數據。
9、索引
從mongoDB 3.0開始ensureIndex被廢棄,使用 createIndex建立索引。建立索引,須要傳遞兩個參數 ①:創建索引的字段名稱,②排序參數 1升序,-1降序。
1)創建單索引。
db.student.createIndex({name:1}) 表示給name字段創建索引,按照升序的排序
2)創建複合索引。
db.student.ensureIndex({name:1,age:-1}) 創建一個複合索引,表示給name和age都創建索引,按照name的升序,和age的降序
10、總結