MongoDB入門

一、基本概念解釋

二、MongoDB 數據類型

下表為MongoDB中常用的幾種數據類型。

ObjectId?類似唯一主鍵,可以很快的去生成和排序,包含 12 bytes,含義是:

前 4 個字節表示創建?unix?時間戳,格林尼治時間?UTC?時間,比北京時間早了 8 個小時

接下來的 3 個字節是機器標識碼

緊接的兩個字節由進程 id 組成 PID

最后三個字節是隨機數

MongoDB 中存儲的文檔必須有一個 _id 鍵。這個鍵的值可以是任何類型的,默認是個 ObjectId 對象

由于 ObjectId 中保存了創建的時間戳,所以你不需要為你的文檔保存時間戳字段,你可以通過 getTimestamp 函數來獲取文檔的創建時間:

> var newObject = ObjectId()

> newObject.getTimestamp()

ISODate("2018-07-05T07:21:10Z")

ObjectId 轉為字符串

> newObject.str

5a1919e63df83ce79df8b38f

三、Mongodb入門命令

3.1、基本查看命令

show dbs 查看所有的數據庫

use databaseName 使用某個數據庫? 例如:use edu

show tables/collections 查看當前庫下的所有collection

3.2、庫和集合的操作

查看當前所處的數據庫

db

3.3、在mongodb中,庫是隱式創建的,你可以use 一個不存在的庫,然后在該庫下創建collection,即可創建庫。

db.dropDatabase(); 刪除database,?把當前所用的庫給刪除了?,?即使里面有數據也會刪除

db.createCollection(‘collectionName’), 創建collection,collection也是允許隱式創建的

db.collectionName.insert(document); 在集合(表)中插入具體數據的時候會自動創建

db.collectionName.drop() , 刪除collection

舉例如下:

use edu #創建數據庫:edu

db.createCollection('video') #創建集合(表):video

db.video.insert({play_url:'http://www.sohu.com/a.mp4',title:'戰狼2',area:'中國'})? ?#插入一條數據

db.video.drop()? ?#刪除集合video

四、Mongodb基本增刪改查

4.1、增加數據

mongodb存儲的是文檔,文檔是json格式的對象,我們向數據庫存儲數據的時候可以使用insert方法,數據格式要以js對象格式進行存儲:

語法:?db.collectionName.insert(document);

db.createCollection('student')

db.student.insert({name:'zhangsan',age:'20'})? 向當前students表里插入數據

4.1.1、增加單篇文檔

語法:?db.student.insert({title:"nice day"});

4.1.2、增加單個文檔,并且指定_ID

語法:?db.student.insert({_id:8,age:78,name:"lisi"});

_id 是我們在插入數據的時候,mongodb自動給文檔添加的一個屬性,如果我們不需要系統分配_id ,可以在添加數據的時候手動設置,覆蓋原有_id ,雖然_id 的類型可以自由指定,但是在同一個集合當中必須唯一,如果插入重復的值,系統會拋出異常.

這個_id 的名稱是固定的,它可以是Mongodb支持的任何數據類型,默認是ObjectId,在關系型數據庫中,主鍵通常是數值型的,并且可以設置自增,而Mongodb的主鍵,原生不支持自增主鍵。

4.1.3、增加多個文檔

db.student.insert( [{time:'friday',value:'mongodb'},{_id:1,gender:'male',name:'QQ'}])

可以以數組的方式,一次性向集合插入多個數據;同時應該注意的是,由于mongodb采用的是?J?a?v?a?S?c?r?ip?t?S?he?l?l,所以我們可以根據js特性,將文檔作為值賦給變量然后進行操作:

j = {name : 'isi'};

t = {name : 'wangwu'};

db.student.insert([j,t]);

4.1.4、SAVE和INSERT的區別

save和insert都可以進行數據的插入和增加,但是也有一些異同:

對于已存在數據?{?_id:1, "name":"n1" },再次進行插入操作時,

a、insert({_id:1, "name" :"n2"}) 會報主鍵重復的錯誤提示;

b、save({ _id:1, " name ":"n2"})?會把?n1?修改為?n2?。

相同點:?若新增的數據中沒有主鍵時,會增加一條記錄。

不同點:?主鍵_id已存在時?:insert 會報錯,save會修改當前_id的數據

即:insert有則報錯,無則插入;save有則修改,無則插入

4.2、查詢操作

4.2.1、FIND()

無條件的普通查詢方式很簡單,可以直接使用

db.collectionName.find(?)?;?一次可以查出指定集合中的所有數據

db.student.find();

按照條件進行查詢操作

語法: db.collection.find(?查詢表達式?,?查詢的列?)?;

例1: db.student.find({},{name:1})??//查詢student集合中的name屬性?(_id屬性默認總是查出來)

例2: db.student.find({},{name:1, _id:0}) //查詢student集合中的name屬性,且不查詢_id屬性此處的0表示的是false,不查詢

例3: db.student.find({age:20},{name:1,_id:0?}?)?;//查詢student集合中age屬性值為20的name屬性

4.2.2、FINDONE()

findOne()和find()函數一樣,只是findOne()返回的是查詢結果中的第一條數據,或者返回null.

4.3、刪除操作

語法: db.collectionName.remove(?查詢表達式?,?選項?);

選項是指?{?justOne:true/false},是否只刪一行, 默認為false?注意

1: 查詢表達式依然是個json對象

2: 查詢表達式匹配的行,將被刪掉.

3: 如果查詢表達式為空對象{},collections中的所有文檔將被刪掉.

例1: db.student.remove({name:'n1'});//刪除stu表中name屬性值為'n1'的文檔

例2: db.student.remove({gender:'m'},true);//刪除stu表中gender屬性為m的文檔,只刪除1行.

4.4、修改操作

語法: db.collection.update(?查詢表達式?,?新值?,?選項?);

*改哪幾行? --- 查詢表達式

*改成什么樣? -- 新值 或 賦值表達式

*操作選項 ----- 可選參數

upsert:如果要更新的那條記錄沒有找到,是否插入一條新紀錄,默認為false

multi? :是否更新滿足條件的多條的記錄,默認為false

multi :是否更新滿足條件的多條的記錄,false:只更新第一條,true:更新多條,默認為false

例:db.student.update({name:'QQ'},{name:'MSN'}); //是指選中student表中,name值為QQ的文檔,并把其文檔值改為{name:"MSN"},

結果:文檔中的其他列也不見了,改后只有_id和name列了。即是新文檔直接覆蓋了舊文檔,而不是修改。

4.4.1、修改操作中的關鍵字

如果是想修改文檔的某列,可以用$set關鍵字

例:db.student.update(query,{$set:{name:’QQ’}})

修改時的賦值表達式

$set 修改某列的值

$unset 刪除某個列

$inc 增長某個列

$rename 重新命名某列

$setOnInsert 當upsert為true時,并且發生了insert操作時,可以補充的字段.

$INC實例

按照指定的步長增長某個列;

db.student.insert({"uid":"201203","type":"1",size:10})

db.student.update({"uid" :"201203"},{"$inc":{"size"? :? 2}})

$UNSET實例

db.student.find({_id:8})

db.student.update({_id:8},{$unset:{age:'sss'}})

4.5 查詢表達式

我們無論在修改刪除還是查詢的過程中,都需要傳入查詢表達式對目標數據進行查詢,表達式有很多種

1:? 最簡單的查詢表達式

{filed:value}? ,是指查詢field列的值為value的文檔

2:? $ne:!=

{field:{$ne:value}}?

db.stu.find({age:{$ne:16}}) 作用--查age列的值 不等于16的文檔

3:$gt:大于

$lt:小于

$gte:大于或等于

$lte:小于或等于

4:? $in:[]? ? 查詢某列的值在范圍內的文檔

db.goods.find({cat_id:{$in:[2,8]}}

5:? $nin:not? in? ? ? 查詢某列不在范圍內的文檔

$nin:[2,3,5]

6:? $exists

語法:? {field:{$exists:1}}

作用:? 查詢出含有field字段的文檔

7:用正則表達式查詢? 以”諾基亞”開頭的商品

例:db.goods.find({goods_name:/諾基亞.*/},{goods_name:1});

五?游標操作

通俗的說,游標不是查詢結果,而是查詢的返回資源,或者接口,通過這個接口,你可以逐條對數據進行讀取;

聲明游標?:

var? cursor? =? db.collectioName.find(query,projection);

cursor.hasNext()? //判斷游標是否已經取到盡頭?

cursor.next()? //取出游標的下1個單元

用while來循環游標

var? mycursor? =? db.bar.find({_id:{$lte:5}})

while(mycursor.hasNext())? { printjson(mycursor.next());}

游標還有一個迭代函數,允許我們自定義回調函數來逐個處理每個單元.

cursor.forEach(回調函數);

var? gettitle? =? function(obj)? {print(obj.goods_name)}

var? cursor? =? db.goods.find();

cursor.forEach(gettitle);

游標在分頁中的應用

比如查到10000行,跳過100頁,取10行,一般地,我們假設每頁N行, 當前是page頁,?就需要跳過前?(page-1)*N 行, 再取N行.

在mongo中,分頁是用skip(), limit()函數來實現的

//查詢結果中,跳過前9995行

var? mycursor? =? db.bar.find().skip(9995);

//查詢第901頁,每頁10條

則是? var? mytcursor? =? db.bar.find().skip(9000).limit(10);

六?group分組

mongodb支持聚合運算;

在goods表中插入數據

db.goods.insert([

{'_id':3,'cat_id':6,'price':29},

{'_id':4,'cat_id':7,'price':30},

{'_id':5,'cat_id':6,'price':31},

{'_id':6,'cat_id':7,'price':32},

{'_id':7,'cat_id':7,'price':28},

])

如果我們所處的是mysql數據庫,我們可以這樣查詢每個類下面的商品平均價格

select? avg(price)? from? goods? group? by? cat_id;

但如果在mongodb下,我們如何查詢分組內的平均值呢? 我們需要使用mongodb的聚合運算?https://docs.mongodb.com/manual/aggregation/

db.goods.aggregate([

{$match:{}},

{$group:{_id:"$cat_id",avg:{$avg:'$price'}}}

]);

其中,$match表示匹配的條件,$group表示分組的條件,$avg表示求平均值. 當然,指令還有很多,我們還可以使用limit,sort等操作

db.goods.aggregate([

{$match:{}},

{$group:{_id:"$cat_id",avg:{$avg:'$price'}}},

{$limit:1}

]);

按照價格降序排列

db.goods.aggregate([

{$match:{}},

{$sort:{price:-1}}

]);

七?MapReduce

7.1、MapReduce原理

隨著大數據興起,MapReduce的概念也越來越火,通常的概念是用于大規模數據集(1TB)的并行運算,實際上就是傳統關系型數據庫的group概念的延伸.

MapReduce之所以能夠流行,是因為數據的大,當數據過大的時候,單個服務器無法承載,facebook,微軟等等的數據中心都是分布在世界各地的,?我們所需?要的數據很可能分布在不同的服務器甚至世界各地.在這時候,我們就無法使用group操作了.

MapReduce通俗的講,最大的優點就是可以支持分布式的group

而MapReduce的操作即分為map和reduce兩步;

map ---> 映 射

reduce ---> 減少,規約,回歸

7.2、MapReduce統計價格

//按照cat_id? 分配? price,把price數據映射到一個數組上 var? map? =? function(){

emit(this.cat_id? ,? this.price)

}

//將映射好的數組進行操作

var? reduce? =? function(cat_id,number){ return? Array.avg(number)

}

//將統計的數據映射到res表當中db.goods.mapReduce(map,reduce,{out:'res'})

接下來我們使用mapReduce功能實現地震數據的統計

7.3、下載并導入地震信息

在國家地震科學數據共享中心下載過去一年的地震數據?http://data.earthquake.cn/sjfw/index.html?PAGEID=datasourcelist&dt=40280d0453e414e40153e44861dd0003

將數據保存為csv格式,導入到mongodb數據庫中,使用mongoimport

-d : 指明導入文件存放在哪個數據庫

-c : 指明導入文件存放在哪個集合

--type:指明要導入的文件格式。

--headerline:指明不導入第一行,csv格式的文件第一行為列名。

--file:指明要導入的文件路徑。

./bin/mongoimport? -d? test? -c? dz? --type? csv? --file? /usr/local/src/dz.csv? --headerline

7.4、按照經緯度統計數據

我們規約的時候按照經緯度的5*5方格進行分組,如果在此方格內存在地震,則地震+1

var? map? =? function(){

var? jd? =? parseInt(this.jd/5)*5; var? wd? =? parseInt(this.wd/5)*5; var? area? =? jd? +? ':'? +? wd;

emit(area,1);//如果該區域有地震,則統計為1

}

var? reduce? =? function(area,nums){ return? Array.sum(nums);

}

db.dz.mapReduce(map,reduce,{out:'dzrs'});

成功獲取區間范圍內的地震次數,此時我們要將數據導出為json,做成熱力圖;

7.5 熱力圖

使?用?百?度?地?圖?開?放?平?臺?的?熱?力?圖?api?http://lbsyun.baidu.com/index.php?title=jspopular

填入密鑰,生成熱力圖

7.6 展示地震數據

轉化地震數據為規定的json格式

var? course? =? db.dzrs.find();

var? row;

course.forEach(function(obj){

? ? row? =? obj._id.split(':');

? ? db.reli.insert({lng:parseInt(row[1])+2.5,lat:parseInt(row[0])+2.5,count:obj.value})

})

導出json

./bin/mongoexport? -d? test? -c? reli? -o? /usr/local/src/reli.json

將json數據放入熱力圖當中并配置熱力圖相關選項.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容

  • 安裝 MongoDB Windowns、Ubuntu17.10 下安裝 MongoDB教程在此 MongoDB 幫...
    Kangvcar閱讀 2,111評論 0 13
  • 關于Mongodb的全面總結 MongoDB的內部構造《MongoDB The Definitive Guide》...
    中v中閱讀 31,985評論 2 89
  • 2018年7月5日筆記 1.MongoDB簡介 1.1 NoSQL數據庫是什么 NoSQL,指的是非關系型的數據庫...
    瀟灑坤閱讀 626評論 0 0
  • 第一章 前言 1.1 知識體系分析 前端工程師:Web前端,也就是在Web應用中用戶可以看得見碰得著的東西。包括W...
    whitsats閱讀 875評論 0 3
  • docker 安裝MongoDB 編輯docker-compose.yml文件 docker-compose up...
    巨子聯盟閱讀 347評論 0 0