關於網路那些事...

網路行銷,SEO,網路趨勢,教學文章,網頁設計,生活時事

MongoDb 筆記

推薦

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’);

如果這篇文章對你有幫助,請在這裡點個讚



最新文章推薦