初識MongoDB-用法和用途

用意:記錄一下本身學習MongoDB的一些體會. 適合範圍, 安裝和用法. 

一. MongoDB相關

JavaScript統一天下
    JavaScript正在快節奏地統一整個web開發流程. JvaScript是WEB前端開發的惟一依靠, 依賴V8引擎的Node.js也正在劃分服務器端的領地, 而數據庫也是JavaScript垂涎已久的領域. MongoDB就是用相似JSON object格式存儲數據的數據庫.
    MongoDB的javascript shell很方便, 能夠去在線嘗試一下  http://try.mongodb.org/.
    關係型數據庫到對象存儲的轉換一直是程序員頭疼的工做. 而MongoDB直接返回JSON object的方式帶來了很大的便利.
MongoDB適合領域
    特別適合存儲 圖片, 長文本等信息, 例如日誌信息,  圖片, 經緯度, 表單, 帳號信息等. MongoDB能夠做爲分佈式文件系統.
    經過 sharding實現負載均衡. 即數據集按某個字段切割到多個服務器上.
    動態scheme機制方便修改數據庫, 快速上線修改應用. 
MongoDB缺點
    不適合多線程: 每次寫操做都會鎖住整個數據庫. 
    管理類工具不豐富.
    數據庫上限是100G

二. 安裝MongoDB

    安裝MongoDB有兩種方式, 源碼安裝和package安裝. 源碼安裝較簡單.

2.1 package安裝

2.1.1 配置源和工具
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list
sudo apt-get update
sudo apt-get install mongodb-10gen
[注: 須要225M]
2.1.2 下載MongDB[最新穩定版本是2.4]
apt-get install mongodb-10gen=2.4.8
避免upgrade升級,使用pin
echo "mongodb-10gen hold" | sudo dpkg --set-selections
2.1.3 Mongo命令
啓動MongDB:
sudo service mongodb start
是否啓動成功,看日誌:/var/log/mongodb/mongodb.log
中止MongDB:
sudo service mongodb stop
重啓MongDB:
sudo service mongodb restart

2.1.4 MongDB文件結構介紹
啓動文件:/etc/rc.d/init.d/mongod
配置文件:/etc/mongod.conf
data文件: /var/lib/mongo
log文件:/var/log/mongo
user帳號:mongod user account

2.2 Linux源碼安裝方式

2.2.1 得到源碼
下載安裝包
curl -O http://downloads.mongodb.org/linux/mongodb-linux-x86_64-2.4.8.tgz
解壓縮包和建立目錄
tar -zxvf mongodb-linux-x86_64-2.4.8.tgz
mkdir -p ~/mongodb
cp -R -n mongodb-linux-x86_64-2.4.8/ ~/mongodb

2.2.2 添加PATH
在~/.bashrc中
export PATH=~/mongodb/mongodb-linux-x86_64-2.4.8/bin:$PATH
[注意$符號,不然PATH就被識別爲路徑名了.]

2.2.3 添加數據庫存儲目錄
建立mongdb用戶
sudo useradd mongdb
設置data目錄
mkdir -p /data/db
chown mongodb /data/db

2.2.4 MongoDB命令
啓動mongoDB
mongod或者~/mongodb/mongodb-linux-x86_64-2.4.8/bin/mongod
mongod [--dbpath <some alternate directory>]
能夠設置data路徑
關閉mongoDB, control+C便可.

MongoDB shell:
     mongo或者~/mongodb/mongodb-linux-x86_64-2.4.8/bin/mongo
     mongo 等價於 mongo localhost:27017/admin

三. MongoDB使用

選擇第二種安裝方式, 由於第一種225M下載太痛苦了.

3.1 基本操做

3.1.1 選擇數據庫
    Mongo默認安裝了三個數據集, foobar\local\test, 數據都在/data/db中.

顯示全部數據集
show dbs
foobar 0.203125GB
local 0.078125GB
test 0.203125GB

顯示當前鏈接數據集
db
test

建立數據集recommend
use recommend
switched to db recommend

萬能的help命令能夠顯示經常使用的命令.

注: 使用show dbs後並無發現recommend數據集. 只有插入數據後,纔會真正建立recommend.
db.person.save({name: "Jimmy"});
show dbs
foobar 0.203125GB
local 0.078125GB
recommend 0.203125GB
test 0.203125GB

問題: 200M, 好大的空間啊? 具體存儲了什麼東西?

3.1.2 建立數據集
與Mysql的區別:Mysql創建數據集須要兩個步驟:創建scheme和插入數據.
MongoDB採用動態scheme的方法,第一次插入數據時,scheme依據數據格式自動生成.
pref1 = {userid : 1, itemid : 12, rate : 3.0};
pref2 = {userid : 2, itemid : 30, rate : 5.0};
db.udata.insert(pref1);
db.udata.insert(pref2);

查看數據集, 顯示插入成功:udata
show collections
person
system.indexes
udata

查看數據集udata數據: 
db.udata.find();
{ "_id" : ObjectId("527df58c3807dc04399c4bec"), "userid" : 1, "itemid" : 12, "rate" : 3 }
{ "_id" : ObjectId("527df58d3807dc04399c4bed"), "userid" : 2, "itemid" : 30, "rate" : 5 }

其中"_id"爲系統自動生成.相似與MD5碼?

3.1.3 插入更多的數據
for (var i = 3; i <= 25; i++) db.udata.insert({userid: Random.randInt(i) + 1, itemid : (Random.randInt(i) + 1)*3, rate : Random.randInt(6)});
db.udata.find();
{ "_id" : ObjectId("527df9153807dc04399c4c16"), "userid" : 9, "itemid" : 24, "rate" : 3 }
{ "_id" : ObjectId("527df9153807dc04399c4c17"), "userid" : 19, "itemid" : 36, "rate" : 1 }
{ "_id" : ObjectId("527df9153807dc04399c4c18"), "userid" : 12, "itemid" : 18, "rate" : 4 }

使用it能夠顯示更多的東西.

3.1.4 cursor查詢數據
    兩種查詢方式: index和next()
3.1.4.1 index下標
var i = db.udata.find();
printjson(i[2]);
{
"_id" : ObjectId("527df9153807dc04399c4c07"),
"userid" : 4,
"itemid" : 9,
"rate" : 2
}
缺陷: 查詢便捷, 可是全部數據加載到了數組中, 消耗大量內存.

3.1.4.2 next()方式
var c = db.udata.find();
while (c.hasNext()) { printjson(c.next()); }
或者
while (c.hasNext()) { print(c.next().userid);  }
5
9
8
優勢: 查詢無需加載整個數據到內存中.

3.1.5 查詢操做
3.1.5.1 返回cursor
var a = db.udata.find({ userid : 18 }); printjson(a.next());
{
"_id" : ObjectId("527df9153807dc04399c4c19"),
"userid" : 18,
"itemid" : 51,
"rate" : 4
}

限定查詢個數: 
db.udata.find({ rate : 1 }).limit(1);
{ "_id" : ObjectId("527df9153807dc04399c4c10"), "userid" : 7, "itemid" : 30, "rate" : 1 }
db.udata.find({ rate : 1 });
{ "_id" : ObjectId("527df9153807dc04399c4c10"), "userid" : 7, "itemid" : 30, "rate" : 1 }
{ "_id" : ObjectId("527df9153807dc04399c4c13"), "userid" : 9, "itemid" : 12, "rate" : 1 }
{ "_id" : ObjectId("527df9153807dc04399c4c17"), "userid" : 19, "itemid" : 36, "rate" : 1 }

3.1.5.2 返回document
var a = db.udata.findOne({ userid : 18 }); printjson(a);
{
"_id" : ObjectId("527df9153807dc04399c4c19"),
"userid" : 18,
"itemid" : 51,
"rate" : 4
}

3.2 db中選擇數據集
var col = db.getSiblingDB("recommend").getCollection("udata");
col.find();
{ "_id" : ObjectId("527df9153807dc04399c4c05"), "userid" : 2, "itemid" : 3, "rate" : 4 }
{ "_id" : ObjectId("527df9153807dc04399c4c06"), "userid" : 3, "itemid" : 12, "rate" : 5 }
...

3.3 CRUD操做[增刪改查]

官方文檔的圖解釋的很清楚 http://docs.mongodb.org/manual/core/crud-introduction/ 
3.3.1 查詢query


查詢格式 : db.collections.find(select [, projection])[.limit()] 

找出全部用戶19的preference
db.udata.find({userid:19}).limit(5);
{ "_id" : ObjectId("527df9153807dc04399c4c17"), "userid" : 19, "itemid" : 36, "rate" : 1 }
{ "_id" : ObjectId("527df9153807dc04399c4c1b"), "userid" : 19, "itemid" : 36, "rate" : 2 }

找出用戶19中評分大於等於2的preference
db.udata.find({userid:19, rate:{$gte:2.0}}).limit(5);
{ "_id" : ObjectId("527df9153807dc04399c4c1b"), "userid" : 19, "itemid" : 36, "rate" : 2 }

找出用戶19中評分小於3的preference,只顯示itemid和userid
db.udata.find({userid:19, rate:{$lt:3.0}}, {itemid:1, userid:1}).limit(5);
{ "_id" : ObjectId("527df9153807dc04399c4c17"), "userid" : 19, "itemid" : 36 }
{ "_id" : ObjectId("527df9153807dc04399c4c1b"), "userid" : 19, "itemid" : 36 }

[select項比較特殊, select除_id外,只能全0或者全1; {itemid:1, userid:0}不容許]
{itemid:1, userid:1, _id:0}

此外sort很管用.
db.udata.find({userid: {$lt:8},rate:{$lt:3.0}}, {_id:0});
{ "userid" : 4, "itemid" : 9, "rate" : 2 }
{ "userid" : 4, "itemid" : 9, "rate" : 0 }
{ "userid" : 3, "itemid" : 18, "rate" : 2 }
{ "userid" : 5, "itemid" : 18, "rate" : 0 }
{ "userid" : 7, "itemid" : 30, "rate" : 1 }

db.udata.find({userid: {$lt:8},rate:{$lt:3.0}}, {_id:0}).sort({rate:1});
{ "userid" : 4, "itemid" : 9, "rate" : 0 }
{ "userid" : 5, "itemid" : 18, "rate" : 0 }
{ "userid" : 7, "itemid" : 30, "rate" : 1 }
{ "userid" : 4, "itemid" : 9, "rate" : 2 }
{ "userid" : 3, "itemid" : 18, "rate" : 2 }

3.3.1 增刪改


插入操做
db.test.insert({age: 1});db.test.insert({age: 1});
db.test.find();
{ "_id" : ObjectId("527e18504afdfbe586145e4d"), "age" : 1 }
{ "_id" : ObjectId("527e18794afdfbe586145e4e"), "age" : 1 }

更新操做,只更新一個[好像是最新的]


db.test.update({age:1}, {$set: {name: "John"}});
db.test.find()
{ "_id" : ObjectId("527e18794afdfbe586145e4e"), "age" : 1 }
{ "_id" : ObjectId("527e18504afdfbe586145e4d"), "age" : 1, "name" : "John" }

更新多個
db.test.update({age:1}, {$set: {name: "Sam"}}, {multi:true});
db.test.find();
{ "_id" : ObjectId("527e18504afdfbe586145e4d"), "age" : 1, "name" : "Sam" }
{ "_id" : ObjectId("527e18794afdfbe586145e4e"), "age" : 1, "name" : "Sam" }

刪除操做


db.test.insert({age: 2})
db.test.find()
{ "_id" : ObjectId("527e18794afdfbe586145e4e"), "age" : 1 }
{ "_id" : ObjectId("527e18504afdfbe586145e4d"), "age" : 1, "name" : "John" }
{ "_id" : ObjectId("527e19094afdfbe586145e4f"), "age" : 2 }
db.test.remove({age:2})
db.test.find()
{ "_id" : ObjectId("527e18794afdfbe586145e4e"), "age" : 1 }
{ "_id" : ObjectId("527e18504afdfbe586145e4d"), "age" : 1, "name" : "John" }

四. 參考資料

[1] http://www.fuchaoqun.com/2011/05/why-mongodb/ [2] MongoDB官方文檔 http://docs.mongodb.org/manual/
相關文章
相關標籤/搜索