推薦

Antoine Girbal’s Corner

##MongoDb可視化操作介面 https://git.oschina.net/xiexiao04/mongo-exprss-master

##安裝MongoDb 安裝 http://www.mongodb.org/downloads 安裝windows 64-bit 2008 R2+ 安裝32-bit 會有2G限制

點擊Msi檔案開始安裝,安裝完成之後,可能會在下方位置 C:\Program Files\MongoDB\Server\3.0\bin

加入環境變數: PATH: ………;C:\Program Files\MongoDB\Server\3.0\bin

以終端機操作,開啟Mongodb Server

	> mongod.exe

確定啟動 前往 http://localhost:27017 預設port,如果成功啟動會顯示: It looks like you are trying to access MongoDB over HTTP on the native driver port. 打開terminal,輸入mongo 啟動database

	> mongo

預設會連結到 test 資料庫 並且是以javascript shell的方式運行,因此js與法在這裡面通常都可以執行

##資料庫 顯示目前所有資料庫

	> show dbs

建立或登入資料庫 建立跟登入資料庫,都是使用use

	> use 資料庫名稱
  
  //switched to db 資料庫名稱

顯示資料庫中所有資料表

	//先登入資料庫
	> use 資料庫名稱
  //顯示資料庫中所有資料表
	> show collections

基本CRUD (參考)

假設資料表名稱為 person

insert mongodb通常會在insert時自動產生一個"_id": ObjectId(“id string”)

		db.person.insert({"name":"adam","age":23})
		db.person.insert({"name":"rober","age":21})
		db.person.insert({"name":"jordan","age":22})

find 通常,一般資料庫都會使用uuid作為唯一辨識ID,而MongoDb則是使用ObjectId,如果要使用uuid功能,可以參考Nodejs這篇的 擴充uuid說明(要登入logdown)。

    > db.person.find()
    //如果想要搜尋ObjectId:
    > db.person.find({_id: ObjectId("id string")})

update

	db.person.update({"name":"adam"},{"name":"adam","age":25})
	db.person.find()

delete

	//刪除資料表內所有資料(Mongodb為不可逆操作,須仔細評估是否全部刪除)
	db.person.remove({})
	//刪除單一筆資料
	db.person.remove({"name":"adam"})

count

	//計算資料總數量
	db.person.count()

查詢

在Mongodb裡面,都將一些查詢參數封裝成變數:

	>, >=, <, <=, !=, =  對應於  "$gt", "$gte", "$lt", "$lte", "$ne", ""

解說:

	> 英文為greater than因此以$gt命名
	< 英文為less than因此以$lt命名
	=英文為equal (e)
	!=英文為 not equal  (ne)
  
AND, OR, IN, NOTIN 對應於 "", "$or", "$in", "$nin"

(=)範例: 取得年齡等於21歲的資料

db.person.find( {"age":21 } )

(>)範例: 取得年齡大於21歲的資料

db.person.find( { "age":{$gt:21} } )

(<)範例: 取得年齡小於21歲的資料

db.person.find( { "age":{$lt:21} } )

(>=)範例: 取得年齡大於等於21歲的資料

db.person.find( {"age":{$gte:21} } )

(<=)範例: 取得年齡大於等於21歲的資料

db.person.find( { "age":{$lte:21} } )

(OR)範例: 取得姓名為adam 或 joeson 或 port 的資料

	db.person.find( { $or: [{"name":"adam"},{"name":"joeson"},{"name":"port"}] } )

(OR)範例: 取得大於20歲及小於20歲的資料

	db.person.find( { $or: [{"age":{$gt:20}},{"age":{$lt:20}}] } )  

(IN)範例: 取得姓名符合adam 、 joeson 、 port 的資料

	db.person.find( { "name": {$in: ["adam","joeson","port"]} } )

正則表示式

Mongodb 可以直接使用正則表示式查詢

  db.person.find({"name": /^a/i })

WHERE查詢

	db.person.find({$where:function(){ return this.name=="adam"}})

進階更新介紹

整列更新 直接以 db.person.update() 更新,是屬於整體更新,如果有時只要更新一個字串或欄位,可以透過局部更新。

局部更新 mongodb提供兩種修改器: $inc和$set 以及 upsert方法 透過這兩個修改器,我們就能更新特定欄位,而不用動到整個列的資料

$inc 累加 $inc 就是 increase 縮寫,會將值加入原本的欄位 例如: 年齡為20,如果使用{$inc:{“age”:35}},則會累積成55

db.person.update({"name":"joeson"},{$inc:{"age":35}})

$set 更新 $set 則是直接更新欄位 例如: 年齡為20,如果使用{$inc:{“age”:35}},則會資料就會更新為35

	db.person.update({"name":"joeson"},{$set:{"age":35}})

UPSERT 智慧化的更新 upsert是mongodb特有的功能,當我們在update時,如果資料不存在就會insert 一筆資料 只要在update時,第三個參數設定為true即可

	db.person.update({"name":"adams"},{$set:{"age":22}},true)

REMOVE 資料

	刪除資料表內所有資料(Mongodb為不可逆操作須仔細評估是否全部刪除)
	db.person.remove()
	刪除單一筆資料
	db.person.remove({"name":"adam"})

COUNT 計算總數

	db.user.count()

DISTINCT 取出不重複資料

	distinct 可以取出某欄位合併後的資料
	db.person.distinct("age")

GROUP

Group 包含有這些函數: key, initial, reduce (或稱"$reduce"), condition, finalize

key 帶表要group的對象,根據這個key來分成不同組 initial 每一個key組別裡,可以提供一個初始物件,預設通常會給空陣列[] reduce 包含cur, prev兩個參數 cur 意思為current,也就是目前的數據文件 prev 代表initial,可以透過 initial.物件名稱.push(值) ,將值加入initial定義的物件中 寫法如下:

	reduce: function(cur, prev){...}  
	也可以寫成 
	"$reduce":function(cur,prev){...}

condition 定義過濾條件 finalize group執行完成後,會觸發此函式 包含 out 參數,代表每個key組,可以藉由 out.名稱 在每組插入新的物件 也可以藉由out取得key組中的值 寫法如下:

	finalize: function(out){  }

範例:

依照年齡分組,並且顯示各組相關的人名

	db.person.group({
	key: {"age":true},
	initial: { "user":[]},
	reduce: function(cur, prev){
	prev.user.push(cur.name)
}
})

依照年齡小於20歲進行分組,並且顯示各組相關人名及各組人員數量

	db.person.group({
	key: {"age":true},
	initial: { "user":[]},
	reduce: function(cur, prev){
	prev.user.push(cur.name)
},
condition: {"age":{$lt:20}},
finalize: function(out){
	out.count=out.user.length
}
})

建立 Secondary indexes

透過 ensureIndex來建立次索引。

	ensureIndex({欄位名稱: 參數}); //透過ensureIndex 來建立次索引。
	參數為 1  -1

1代表increasing order;如果改成"field": -1則會以decreasing的方式存放。這一點在輸出時如果要sort資料就會影響到效能。

例如:

	db.person.ensureIndex({name:1};
要取消已建立的次索引,用
	db.person.dropIndex(name);
	
	db.person.dropIndex({name:-1})
須留意的是,索引不能重複。想知道更多關於建立索引,可以參考[http://blog.xuite.net/flyingidea/blog/68050501-%5BmongoDB%5Dindex%E5%8A%9F%E8%83%BD%E7%9A%84%E7%AD%86%E8%A8%98](http://blog.xuite.net/flyingidea/blog/68050501-%5BmongoDB%5Dindex%E5%8A%9F%E8%83%BD%E7%9A%84%E7%AD%86%E8%A8%98)

MapReduce

MapReduce說明[[http://sls.weco.net/CollectiveNote20/MR](http://sls.weco.net/CollectiveNote20/MR)]。
簡介: Map(映射)、Reduce(歸納)

MapReduce 是一個能輕鬆平行分布到多個主機的方法,會先將問題拆分,再將拆分的部分傳送到不同的主機、讓每一台主機進行運算,運算完成的時候,再把結果進行彙整。

MapReduce 能做到count、distinct、group的功能,但是速度較慢。

建議實際應用要將MapReduce放在後端排程執行,不要放在前端做即時回應。 (此段參考MongoDB權威指南)

以下以Hadoop的MapReduce來做說明:

根據上圖: Input: 輸入了一筆要搜尋的資料。平行處理的資料量通常很巨大,因此要先將這筆資料進行拆分成不同的區塊。

spliting: 資料拆分成不同的區塊,可以稱為split或shard(分片)。split數量通常會>=Map workers,這些數量稱為Map Task。Spliti可以預設最大值,例如 spliting=64Mb,若input為500Mb的檔案,則會自動產生8個Map task。 Map: 每一個Map (workers)節點,都具有相同的環境跟條件,接收資料之後就會進行比對分析,取得結果,這些結果為json格式,暫存到記憶體中,並且逐一暫存於硬碟,藉由partition function 將任務指派給Reduce workers

Shuffing: Map取得結果,Shuffle(Reduce workers)會將資料統一進行整理及根據key排序

Reduce: Shuffe將資料傳給Reduce function,Reduce就會根據key將value存成value list,並且執行完畢就會output json型態到記憶體中。

Mongodb的MapReduce

MapReduce 主要應用在分部計算中,分別有Map 函式 及 Reduce 函式。 參考 http://www.csdn.net/article/2013-07-08/2816155-MongoDB-MapReduce-Optimization http://www.kafka0102.com/2010/09/329.html

先建立1000萬筆資料

for (var i = 0; i < 10000000; ++i){ db.uniques.insert({ dim0: Math.floor(Math.random()*1000000) });}

大概需要跑60分鐘,可以用db.uniquest.count() 追蹤目前新增到第幾筆

一次性的變數

在mongodb中,將DB取出的資料存在變數中,提取一次後,就會清空。
	>var list = db.person.find()
	> list
	>....//列出db內容
	> list
	> //第二次則為空值

##PHP擴充mongodb 安裝擴充 前往PHP官方的下載區( 參考最新日期 ) https://s3.amazonaws.com/drivers.mongodb.org/php/index.html Apache Server 選 VC6(Apache 1 or Apache2) or VC11 ,IIS 選 VC9 更多版本選擇可以參考http://windows.php.net/download/ 我使用 PHP5.5.11版本 因此使用 extension=php_mongo-1.6.6-5.5-vc11.dll; 安裝完成之後,可以檢查phpinfo();是否出現mongo

PHP測試操作Mongodb http://blog.toright.com/posts/3840/mongodb-%E6%95%99%E5%AD%B8-%E7%95%B6-php-%E9%81%87%E4%B8%8A-mongodb.html

<?php 
//http://php.net/manual/en/mongo.tutorial.php

$m = new MongoClient();
$db = $m->test;
$person = $db->person->find();
foreach($person as $row){
	echo $row['name'].','.$row['age'].'<br>';
}
?>

產生資料庫帳號及密碼 這裡將說明如何建立的資料庫帳密,必須經過驗證才能與資料庫溝通 http://docs.mongodb.org/manual/tutorial/add-user-administrator/ 系統管理者

use admin
db.createUser(
  {
    user: "siteUserAdmin",
    pwd: "password",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

單一資料管理者

use records
db.createUser(
  {
    user: "recordsUserAdmin",
    pwd: "password",
    roles: [ { role: "userAdmin", db: "records" } ]
  }
)

重新啟動mongodb server啟動驗證及登入

	> mongod --auth
<?php 
$m = new MongoClient("mongodb://USERNAME:PASSWORD@127.0.0.1/test");
$db = $m->test;

$person = $db->person->count();
print_r($person);

die();

$preson = $db->person->find();

foreach($person as $row){
	echo $row['name'].','.$row['age'].'<br>';
}

?>

也可以從terminal登入

	>use test
	>db.auth(‘username’,’password’);