MongoDB系列:2、MongoDB經常使用操做練習

 

  最近在自學MongoDB,在此記錄一下,當作學習筆記了(不斷更新中)!!sql

1、背景mongodb

  MongoDB 是一個基於分佈式文件存儲的數據庫。由 C++ 語言編寫。旨在爲 WEB 應用提供可擴展的高性能數據存儲解決方案。它是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。MongoDB 將數據存儲爲一個文檔,數據結構由鍵值(key=>value)對組成。MongoDB 文檔相似於 JSON 對象。字段值能夠包含其餘文檔,數組及文檔數組。數據庫

  其放棄關係模型的緣由就是爲了得到更加方便的擴展、穩定容錯等特性。面向文檔的基本思路就是:將關係模型中的「行」的概念換成「文檔(document)」模型。面向文檔的模型能夠將文檔和數組內嵌到文檔中。所以,實際中能夠用一條數據表示很是複雜的結構。MongoDB沒有預約義模式:文檔的鍵(key)和值(value)再也不是固定的類型和大小,並且根據需求要添加或者刪除字段變得更容易了。數組

  實際應用中,隨着數據量的增大,數據庫都要進行擴展。擴展有縱向擴展和橫向擴展。縱向擴展是使用計算能力更強的機器,也是最省力的方法,可是很容易達到物理極限,不管花多少錢也買不到最新的機器了。橫向擴展就是經過分區將數據分散到更多的機器上。MongoDB的設計採用橫向擴展。面向文檔的數據模型使它很容易地在多臺服務器之間進行數據分割。還能夠自動處理跨集羣的數據和負載,自動從新分配文檔,以及將用戶請求路由到正確的機器上。開發者根本不用考慮數據庫層次的擴展問題,須要擴展數據庫時,在集羣中添加機器便可,MongoDB會自動處理後續的事情。 服務器

 

 

2、MongoDB的優點與劣勢

優點

    1. 快速!基於內存,將熱數據存放在物理內存中(不只僅只是索引和少部分數據),從而提升了總體速度和效率。
    2. 高擴展性!MongoDB的高可用和集羣架構擁有十分高的擴展性。
    3. 自身的FailOver機制!在副本集中,當主庫遇到問題,沒法繼續提供服務的時候,副本集將選舉一個新的主庫繼續提供服務。
    4. JSon格式的數據!MongoDB的Bson和JSon格式的數據十分適合文檔格式的存儲與查詢。

劣勢

    1. 應用經驗少!因爲NoSQL興起時間短,應用經驗相比關係型數據庫較少。
    2. 因爲以往用到的都是關係型數據庫,可能會形成使用者一開始的不適應。
    3. 無事務機制!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>
   }
)
複製代碼

參數說明:

    • query : update的查詢條件,相似sql update查詢內where後面的。
    • update : update的對象和一些更新的操做符(如$,$inc...)等,也能夠理解爲sql update查詢內set後面的
    • upsert : 可選,這個參數的意思是,若是不存在update的記錄,是否插入objNew,true爲插入,默認是false,不插入。
    • multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,若是這個參數爲true,就把按條件查出來多條記錄所有更新。
    • writeConcern :可選,拋出異常的級別。

例:

db.person.insert([{"name":"chen","age":15},{"name":"li","age":20},{"name":"zhang","age":20}]);

$ set修改符

用於修改鍵的值,若是鍵不存在就增長鍵

//將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})

$inc修改符

用於增長已有鍵的值,若是鍵不存在就建立,只能用於整形、長整型、浮點型。

//將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})

$unset修改符

刪除鍵相似關係數據庫的刪除字段操做,要區別$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、總結

相關文章
相關標籤/搜索