MangoDB 學習指南

安裝篇

下載安裝

curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.2.10.tgz
    tar zxvf mongodb-linux-x86_64-rhel62-3.2.10.tgz
    mv mongodb-linux-x86_64-rhel62-3.2.10 /usr/local/
    mv mongodb-linux-x86_64-rhel62-3.2.10 mongodb

    mkdir /data/db
    touch /var/logs/mongodb/mongodb.logs
    cd mongdb/bin && vim mongodb.conf

配置mongodb.conf

dbpath=/data/db
logpath=/var/logs/mongodb
port=27017
#fork=true
#nohttpinterface=true

 從新綁定mongodb的配置文件地址和訪問IP

/usr/local/mongodb/bin/mongod --bind_ip localhost -f /usr/local/mongodb/mongodb.conf
能夠經過 /usr/local/mongodb/bin/mongod --help 查看幫助 ,其中 -f(--config) 配置文件,--bind_ip 綁定ip
/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf 添加到 /etc/rc.d/rc.local 開機啓動php

測試

其中 mongod --config /usr/local/mongodb/mongodb.conf 服務以後,啓動 /usr/local/mongodb/bin/mongo 客戶端,支持JavaScript 版本,show dbs 查看數據庫,db.version() 查看版本前端

查看當前mongodb進程信息

ps -ef | grep mongod //查看進程號碼
cat /proc/24283/limits //查看具體信息java

php的擴展與測試

擴展包地址mysql

cd mongodb-1.1.9
/usr/php/bin/phpize
./configure --with-php-config=/usr/askphp/bin/php-config 
make;make install

PHP代碼

建立集合
$m = new \MongoClient();
    $db = $m->selectDB("test");
    $collection = $db->createCollection("my_col");
插入文檔
$m = new \MongoClient();
    $db = $m->selectDB("test");
    $collection = $db->my_col;
    $document = array(
                "title" => "MongoDB",
                "description" => "database",
                "likes" => 100,
                "url" => "http://www.baidu.com",
                "by"=>"change.net"
                );
    $ret_ins  = $collection->insert($document);
查找文檔
$m = new \MongoClient();
    $db = $m->selectDB("test");
    $collection = $db->my_col;
    $cursor = $collection->find();
    foreach ($cursor as $document) {
        echo $document["title"] . "\n";
    }
更新文檔
$m = new \MongoClient();
    $db = $m->selectDB("test");
    $collection = $db->my_col;
    $collection->update(array("title"=>"MongoDB"), array('$set'=>array("title"=>"MongoDB")));
    $cursor = $collection->find();
    foreach ($cursor as $document) {
        echo $document["title"] . "\n";
    }
刪除文檔
$m = new \MongoClient();
    $db = $m->selectDB("test");
    $collection = $db->my_col;
    $collection->remove(array("title"=>"MongoDB"),  array("justOne" => true));

    $cursor = $collection->find();
    foreach ($cursor as $document) {
        echo $document["title"] . "\n";
    }

使用篇

Start Mongod && Command

mongod
ps aux | grep mongo

-- Start the Mongo Shell
mongo
show dbs
use meals-development
show collections
show users
show roles
show profile
show databases

db.auth()
db.help()
-- collection 爲集合的意思 查看更多幫助,查詢幫助
db.collection.help()
db.collection.find().help()

db.collection.findOne()
db.collection.find().toArray()


db.collection.insert()
db.collection.update()
db.collection.save()
db.collection.remove()
db.collection.drop()
db.collection.createIndex()
db.getSiblingDB()

Data Types 類型比較

參考linux

Date
  • Date() method which returns the current date as a string.
  • new Date() constructor which returns a Date object using the ISODate() wrapper.
  • ISODate() constructor which returns a Date object using the ISODate() wrapper.
ObjectId

new ObjectIdgit

NumberLong && NumberInt

NumberLong("2090845886852")。demo:github

db.collection.insert( { _id: 10, calc: NumberLong("2090845886852") } )
db.collection.update( { _id: 10 },{$set:{ calc: NumberLong("2555555000000")}})sql

db.collection.update( { _id: 10 },{$inc:{ calc: NumberLong(5) } } )mongodb

Check Types

  • instanceof -- mydoc._id instanceof ObjectId
  • typeof -- typeof mydoc._id

SQL && MongoDB Mapping Chart

sql與nosql的不一樣於區別參考

Executables
--- MySQL/Oracle MongoDB
Database Server mysqld/oracle mongod
Database Client mysql/sqlplus mongo
Terminology and Concepts
SQL Terms/Concepts MongoDB Terms/Concepts
database database
table collection
row document or BSON document
column field
index index
table joins embedded documents and linking
primary key,Specify any unique column or column combination as primary key. primary key,In MongoDB, the primary key is automatically set to the _id field.

Create and Alter and CURD

db.users.insert( {
    user_id: "abc123",
    age: 55,
    status: "A"
 } )
 
 -- However, you can also explicitly create a collection:
 db.createCollection("users")
 
 db.users.ensureIndex( { user_id: 1 } )
 db.users.ensureIndex( { user_id: 1, age: -1 } )
 db.users.drop()
 
 
 db.users.find()
 db.users.find(
    { },
    { user_id: 1, status: 1 }
)

db.users.find(
    { },
    { user_id: 1, status: 1, _id: 0 }
)

db.users.find(
    { status: "A" },
    { user_id: 1, status: 1, _id: 0 }
)
db.users.find(
   { age: { $gt: 25, $lte: 50 } }
)
db.users.find(
   { user_id: /^bc/ }
)
db.users.find( { status: "A" } ).sort( { user_id: 1 } )

db.users.count()
db.users.find().count()

db.users.count( { user_id: { $exists: true } } )
db.users.find( { user_id: { $exists: true } } ).count()

db.users.count( { age: { $gt: 30 } } )
db.users.find( { age: { $gt: 30 } } ).count()

db.users.distinct( "status" )

db.users.findOne()
db.users.find().limit(1)

db.users.find().limit(5).skip(10)
db.users.find( { status: "A" } ).explain()

db.users.update(
   { age: { $gt: 25 } },
   { $set: { status: "C" } },
   { multi: true }
)

db.users.update(
   { status: "A" } ,
   { $inc: { age: 3 } },
   { multi: true }
)


db.users.remove( { status: "D" } )
db.users.remove( )

詳細使用

INSERTING DATA
db.customers.insert({  
    first_name: "chris",
    last_name:  "aiv" 
})

--Append a lot of data into a customer
db.customers.insert({  
    first_name: "Peter",
    age: 32,
    address: {
        street: "120 Main St",
        city: "Chicago",
        state: "Illinois",
        zip: "38475"
    },
    phone: {
        home: "5555555555",
        work: "4444444444",
        mobile: "3333333333"
    },
    services: [
        {
            service_id: "time warner"
        },
        {
            service_id: "pge"
        },
        {
            service_id: "moviepass"
        }
    ],
    services_count: 3
});

-- Append data to a customer

db.customers.insert({  
    first_name: "Billy",
    last_name:  "Corgan",
    gender: "m"
})

-- Insert multiple customers in one query

db.customers.insert([  
    {
    first_name: "Jimmy",
    last_name:  "Hendrix"
    },
    {
    first_name: "Jimmy",
    last_name:  "Page"
    },
    {
    first_name: "Kurt",
    last_name:  "Cobain"
    },
    {
    first_name: "Adrian",
    last_name:  "Belew"
    },
    {
    first_name: "Billy",
    last_name:  "Corgan"
    }
])
FINDING DATA
db.customers.find({ first_name: "Peter"}, { services: 1})  
db.customers.find({ first_name: "Peter"}, { "services.service_id": 1})  
db.customers.findOne(  
    { first_name: /^billy$/i },
    { first_name: 1 }
)

db.customers.find({  
    gender: "male"
})

db.customers.find({  
    gender: /(m|male)/i, first_name: /^billy$/i 
})
UPDATING DATA
-- 慎用,破壞式的更新
db.customers.update(  
    { first_name: "Jimmy" },
    { last_name:  "Hendrix"}
)
-- Gentel Update 
db.customers.update(  
    { last_name: /^hendrix$/i },
    { $set: { first_name: "Jimmy" } }
)

-- Increment a value in a field
db.customers.update(  
    { first_name: "Billy" },
    { $inc: { age: 1 }
    }
)

-- Update or Insert a field using an object ID
db.customers.update(  
    { _id: ObjectId("581fef808e5fac221dea48ef") },
    {
        $set: {
            first_name:"Lucy",
            gender: "m",
            age: 40,
            birthdate: new Date("2016-11-02")
        }
    }
)
-- Update a field using someones first name
db.customers.update(  
    { first_name: "Jimmy" },
    {
        $set: {
            gender: "male",
            age: 50,
            birthdate: new Date("Aug 20, 1985")
        }
    },
    { upsert: true }
)
-- Add to an existing document
db.customers.update(  
    { first_name: "Jimmy" },
    { $push: {
        services: {
            service_id: 'hosting windows',
            service_name: "windows hosting"
        }
        }
    }
)
-- 第三個參數,若是條件默認不存在,則新增爲true表示新增的,默認爲false,第四個參數表示所有更新
db.customers.update({first_name:"jack"},{$inc:{age:2}},true);
db.customers.update({first_name:"Jimmy"},{$inc:{age:3}},false,true);
db.customers.update({first_name:"Kurt"},{$inc:{age:-2}});
REMOVING DATA
--Remove a field
db.customers.update(  
    { last_name: "Page" },
    { 
        $unset: { age: 1 }
    }
)

db.customers.update({first_name:"jack"},{$inc:{age:1}})
--Remove a customer
db.customers.remove(  
    //!!! DO NOT US THIS
    { first_name: "Billy"}, true 
)
-- Remove any customer above the age of 31
db.customers.remove(  
    { age: { $gt: 31 } }
    , true
)
DELETING DATA
-- Delete a collection
db.customers.drop()
SEARCHING DATA
{
  _id: 1,
  name: { first: 'John', last: 'Backus' },
  birth: new Date('Dec 03, 1924'),
  death: new Date('Mar 17, 2007'),
  contribs: [ 'Fortran', 'ALGOL', 'Backus-Naur Form', 'FP' ],
  awards: [
            { award: 'National Medal',
              year: 1975,
              by: 'NSF' },
            { award: 'Turing Award',
              year: 1977,
              by: 'ACM' }
          ]
}
db.users.find({awards: {$elemMatch: {award:'National Medal', year:1975}}})


--  $gt,gte,$lt,$lte,$ne
db.col.find({"by":"菜鳥教程"}).pretty()
db.col.find({"likes":{$lt:50}}).pretty()
db.col.find({"likes":{$ne:50}}).pretty()
db.users.find({"likes" : {$gt : 100}})

-- and or 使用
db.customers.find({$or: [{key1: value1}, {key2:value2}]}).pretty()
db.col.find({"likes": {$gt:50}, $or: [{"by": "教程"},{"title": "MongoDB 教程"}]}).pretty()
//支持js
db.customers.find({$where:function(){ return this.first_name=="jack"}})

-- 正則查詢

db.customers.find({name:{$regex:"yaolan.com"}})
-- 或者
db.customers.find({name:/yaolan.com/})
-- 不區分大小寫
db.customers.find({name:{$regex:"yaolan.com",$options:"$i"}})

關於統計,排序,分頁,分組等

  • db.collections.help() 查看更多操做
  • db.collection.find().help();
db.customers.distinct("first_name");
db.customers.count({first_name:"Jimmy",age:{$gt:1}});
db.customers.count({first_name:"Jimmy",age:{$in:[8,90]}});

-- 用於分頁
db.customers.find().limit(2).skip(1)
-- 用於排序,其中value爲1 或 -1 分別爲升降序
db.customers.find().sort({first_name:1});
db.customers.find().sort({first_name:-1});

-- 分組 
-- key :按照那個字段分組
-- initial:初始化函數
-- reduce 函數第一個參數當前文檔,第二個參數爲前一個集合對象
-- condition: 這個就是過濾條件。
-- finalize: 每一組文檔執行完後,多會觸發此方法,那麼在每組集合裏面加上count也就是它的活了
db.customers.group({
    key:{age:true},
    initial:{customers:[]},
    reduce:function(curr,prev){ prev.customers.push(curr.first_name) }
});

db.customers.group({
    key:{age:true},
    initial:{obj:[]},
    reduce:function(curr,prev){ 
        prev.obj.push(curr.first_name); 
        prev.obj.push(curr.last_name);
        prev.obj.push({address:"abc"});
    }
});

-- 存儲整個值
db.customers.group({
    key:{age:true},
    initial:{obj:[]},
    reduce:function(curr,prev){ 
        prev.obj.push(JSON.stringify(curr)); 
    }
});

-- 刪選條件加,每次執行完事件
db.customers.group({
    key:{age:true},
    initial:{obj:[]},
    condition:{age:{$gt:7}},
    reduce:function(curr,prev){ 
        prev.list = JSON.stringify(curr);   
    },
    finalize:function(prev){
        prev.count =  prev.obj.length;
    }
});
aggregate 聚合

按照age分組,並以sum的value累計計算和, 聚合,實例相似sql語句: select by_user, count(*) from mycol group by by_user,在上面的例子中,咱們經過字段by_user字段對數據進行分組,並計算by_user字段相同值的總和。

db.customers.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])


db.customers.aggregate([{$group : {_id: "$age",num:{$sum:2}}}])
db.customers.aggregate([{$group : {_id: "$age",num:{$avg:1}}}])
管道的概念

管道在Unix和Linux中通常用於將當前命令的輸出結果做爲下一個命令的參數。

  • $project:修改輸入文檔的結構。能夠用來重命名、增長或刪除域,也能夠用於建立計算結果以及嵌套文檔。
  • $match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操做。
  • $limit:用來限制MongoDB聚合管道返回的文檔數。
  • $skip:在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。
  • $unwind:將文檔中的某一個數組類型字段拆分紅多條,每條包含數組中的一個值。
  • $group:將集合中的文檔分組,可用於統計結果。
  • $sort:將輸入文檔排序後輸出。
  • $geoNear:輸出接近某一地理位置的有序文檔。
db.article.aggregate(
        { $project : {
            title : 1 ,
            author : 1 ,
        }}
     );

    db.customers.aggregate({$project:{first_name:1,age:1}})


    db.article.aggregate(
    { $project : {
        _id : 0 ,
        title : 1 ,
        author : 1
    }});
    -- $match用於獲取分數大於70小於或等於90記錄,而後將符合條件的記錄送到下一階段$group管道操做符進行處理。
    db.articles.aggregate( [
        { $match : { score : { $gt : 70, $lte : 90 } } },
        { $group: { _id: null, count: { $sum: 1 } } }
       ] );

    -- 通過$skip管道操做符處理後,前五個文檔被"過濾"掉。
    db.article.aggregate({ $skip : 5 });

mapReduce

Map-Reduce是一種計算模型,簡單的說就是將大批量的工做(數據)分解(MAP)執行,而後再將結果合併成最終結果(REDUCE)。

map :映射函數 (生成鍵值對序列,做爲 reduce 函數參數)。
reduce 統計函數,reduce函數的任務就是將key-values變成key-value,也就是把values數組變成一個單一的值value。。
out 統計結果存放集合 (不指定則使用臨時集合,在客戶端斷開後自動刪除)。
query 一個篩選條件,只有知足條件的文檔纔會調用map函數。(query。limit,sort能夠隨意組合)
sort 和limit結合的sort排序參數(也是在發往map函數前給文檔排序),能夠優化分組機制
limit 發往map函數的文檔數量的上限(要是沒有limit,單獨使用sort的用處不大)

db.collection.mapReduce(
   function() {emit(key,value);},  //map 函數
   function(key,values) {return reduceFunction},   //reduce 函數
   {
      out: collection,
      query: document,
      sort: document,
      limit: number
   }
)

-- demo
db.posts.mapReduce( 
   function() { emit(this.user_name,1); }, 
   function(key, values) {return Array.sum(values)}, 
      {  
         query:{status:"active"},  
         out:"post_total" 
      }
)

遊標

針對這樣的操做,result其實並無獲取到customers中的文檔,而是申明一個「查詢結構」,for或者next()一次性加載過來,而後讓遊標逐行讀取,當咱們枚舉完了以後,遊標銷燬。
var result = db.customers.find().limit(2).skip(1)
var result = db.customers.find();
result.forEach(function(curr){
print(curr.first_name);
});

索引

-- 性能分析函數
db.customers.find({age:7}).explain();
-- hint 強制使用索引
db.customers.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})
db.customers.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain();

-- 創建索引 (`ensureIndex` 將要被 `createIndex` 替代)
db.customers.ensureIndex({"first_name":1})
db.customers.createIndex({"first_name":1})
db.customers.createIndexes([{"first_name":1},{"age":-1}])
-- 惟一索引
db.customers.ensureIndex({"first_name":1},{"unique":true})
-- 聯合索引
db.customers.ensureIndex({"first_name":1,"age":-1})
db.customers.createIndexes([{"first_name":1},{"age":-1}])
-- 查看索引
db.customers.getIndexes();
--刪除索引
db.customers.dropIndex("first_name_1") 
db.customers.dropIndex({"first_name":1})
db.customers.dropIndexes();

Mongodb複製

mongod --help

主從讀寫分離(舊版本的,將用replica 副本集代替)

經過主數據庫的OpLog日誌來複制,若是配置成功可看見sync_pullOpLog

-- 一主兩從,主服務器不寫默認端口 27017
mongod --dbpath=E:\MongoDB\datamaster --master
mongod --dbpath=E:\MongoDB\dataslave --port=27018 --slave --source=127.0.0.1:27017
mongod --dbpath=E:\MongoDB\dataslave1 --port=27019 --slave --source=127.0.0.1:27017
-- 測試同步
mongo 127.0.0.1:27017
db.users.insert({name:"tom",age:10})
db.users.insert({name:"lucy",age:13})

-- 在從服務器上查看
db.usrs.find();

主從配置好以後,從服務器默認是不可讀取的,若是出現了 error: { "$err" : "not master and slaveok=false", "code" : 13435 } 這個錯誤,須要在從服務器上執行rs.slaveok(),以後再從服務器上查詢便可。

副本集(代替舊的主從)( --replSet)

  1. 該集羣沒有特定的主數據庫
  2. 若是哪一個主數據庫宕機了,集羣中就會推選出一個從屬數據庫做爲主數據庫頂上,這就具有了自動故障恢復功能

    N 個節點的集羣(至少3個)
    任何節點可做爲主節點
    全部寫入操做都在主節點上
    自動故障轉移
    自動恢復

replica

咱們使用同一個MongoDB來作MongoDB主從的實驗, 操做步驟以下:
關閉正在運行的MongoDB服務器。
mongod --port 27017 --dbpath=E:\MongoDB\datamaster --replSet rs0
以上實例會啓動一個名爲rs0的MongoDB實例,其端口號爲27017。
啓動後打開命令提示框並鏈接上mongoDB服務。
在Mongo客戶端使用命令rs.initiate()來啓動一個新的副本集。
咱們可使用rs.conf()來查看副本集的配置
查看副本集狀態使用 rs.status() 命令

在不一樣機機子上,須要創建集羣名稱,具體能夠參考以下:(示例在一個機子上,用端口區分)

mongod --dbpath=E:\MongoDB\replsetmaster --port=27017  --replSet replset
mongod --dbpath=E:\MongoDB\replsetslave --port=27018 --replSet replset
mongod --dbpath=E:\MongoDB\replsetslave1 --port=27019  --replSet replset
-- 在任意一個`mongo` 初始化副本集,replset 爲上面的副本集名稱

rs.initiate({
    _id:"replset",
    members:[
    {
        _id:0,
        host:"127.0.0.1:27017"
    },
    {
        _id:1,
        host:"127.0.0.1:27018"
    },
    {
        _id:2,
        host:"127.0.0.1:27019"
    }
    ]
})


-- 測試同步
mongo 127.0.0.1:27017
db.users.insert({name:"tom",age:10})
db.users.insert({name:"lucy",age:13})

-- 在第二個服務器上查看
db.usrs.find();
-- 若是出現錯誤`not master and slaveok=false` ,默認是從主節點讀寫數據的,副本節點上不容許讀,須要設置副本節點能夠讀,而後執行 `db.getMongo().setSlaveOk()` 或者`rs.slaveOk()`便可


-- rs.addArb() 使用這個追加一個仲裁服務器
mongod --dbpath=xxxx --port=27020 --replSet replset
rs.addArb("192.168.1.2:27020")

-- rs.add 陸續增長更多的副本
rs.add("192.168.1.2:27021")

最後查看副本集狀態使用 rs.status() 命令。判斷當前運行的Mongo服務是否爲主節點可使用命令db.isMaster(),MongoDB的副本集與咱們常見的主從有所不一樣,主從在主機宕機後全部服務將中止,而副本集在主機宕機後,副本會接管主節點成爲主節點,不會出現宕機,無縫切換

分片技術(Shard)

在Mongodb裏面存在另外一種集羣(cluster),就是分片技術,能夠知足MongoDB數據量大量增加的需求。

複製全部的寫入操做到主節點
延遲的敏感數據會在主節點查詢
單個副本集限制在12個節點
當請求量巨大時會出現內存不足。
本地磁盤不足
垂直擴展價格昂貴

MongoDB Cluster

  • Shard:用於存儲實際的數據塊,實際生產環境中一個shard server角色可由幾臺機器組個一個replica set承擔,防止主機單點故障
  • Config Server:mongod實例,存儲了整個 ClusterMetadata,其中包括 chunk信息。
  • Query Routers: 前端路由,客戶端由此接入,且讓整個集羣看上去像單一數據庫,前端應用能夠透明使用。

模擬在單機上啓用不一樣的端口,分片

-- 服務器分佈
Shard Server 1:27020
Shard Server 2:27021
Shard Server 3:27022
Shard Server 4:27023
Config Server :27100
Route Process:40000

-- 1. 啓動Shard Server
mkdir -p /www/mongoDB/shard/s0
mkdir -p /www/mongoDB/shard/s1
mkdir -p /www/mongoDB/shard/s2
mkdir -p /www/mongoDB/shard/s3
mkdir -p /www/mongoDB/shard/log

/usr/local/mongoDB/bin/mongod --port 27020 --dbpath=E:/MongoDB/shard/s0 --logpath=E:/MongoDB/shard/log/s0.log --logappend
/usr/local/mongoDB/bin/mongod --port 27021 --dbpath=E:/MongoDB/shard/s1 --logpath=E:/MongoDB/shard/log/s1.log --logappend
/usr/local/mongoDB/bin/mongod --port 27022 --dbpath=E:/MongoDB/shard/s2 --logpath=E:/MongoDB/shard/log/s2.log --logappend
/usr/local/mongoDB/bin/mongod --port 27023 --dbpath=E:/MongoDB/shard/s3 --logpath=E:/MongoDB/shard/log/s3.log --logappend

-- 2. 啓動Config Server,這裏只有一臺config server 若是不是一臺,添加 `--configsvr` 參數
mkdir -p /www/mongoDB/shard/config
/usr/local/mongoDB/bin/mongod --port 27100 --configsvr --dbpath=E:/MongoDB/shard/config --logpath=E:/MongoDB/shard/log/config.log --logappend

-- 3. 啓動Route Process,mongos啓動參數中,chunkSize這一項是用來指定chunk的大小的,單位是MB,默認大小爲200MB.

/usr/local/mongoDB/bin/mongos --port 40000 --configdb localhost:27100 --logpath=E:/MongoDB/shard/log/route.log --chunkSize 200

-- 4. 配置Sharding,使用MongoDB Shell登陸到mongos,添加Shard節點,而後按照普通的mongo數據庫那樣,將數據庫鏈接接入接口40000
/usr/local/mongoDB/bin/mongo admin --port 40000


db.runCommand({ addshard:"localhost:27020" })
db.runCommand({ addshard:"localhost:27021" })
db.runCommand({ addshard:"localhost:27022" })
db.runCommand({ addshard:"localhost:27023" })
db.runCommand({ enablesharding:"test" })
db.runCommand({ shardcollection: "users", key: { id:1,time:1}})
-- 或者下面寫寫法是同樣的
sh.addShard("localhost:27020");
sh.addShard("localhost:27021");
sh.addShard("localhost:27022");
sh.addShard("localhost:27023");
sh.enableSharding("test");
-- sh.shardCollection("<database>.<collection>", shard-key-pattern) 按照collection的key來分片
sh.shardCollection("test.users",{"name":1,"_id":1});

-- 5. 插入數據,測試分片
    use test

    for(var i=0;i<=100000;i++) {
        db.users.insert({name:"lucy"+i,age:i});
    }

-- 6. 查看分片信息
sh.status()

安全管理

  1. 以安全認證模式啓動
    mongod --auth --dbpath /usr/mongo/data -f /var/mongo.log
    使用--auth選項啓動mongod進程便可啓用認證模式。
    或者,也能夠修改/etc/mongodb.conf,設置auth=true,重啓mongod進程。
  2. 添加用戶
-- 建立用戶
db.createUser({  
    "user": "chrisaiv",
    "pwd": "password",
    "roles": [
        { role: "clusterAdmin", db: "admin" },
        { role: "readAnyDatabase", db: "admin" },
        "readWrite"
        ]
    },
    { w: "majority", wtimeout: 5000 }
)

測試數據庫安全認證: `db.auth("admin", "123456")`
  1. 爲數據庫寫數據(同步到磁盤)加鎖
    db.runCommand({fsync:1,lock:1})
    說明:該操做已經對數據庫上鎖,不容許執行寫數據操做,通常在執行數據庫備份時有用。

  2. 查看當前鎖狀態
    db.currentOp()

  3. 解鎖
    use local db.$cmd.sys.unlock.findOne()
    說明:
    執行解鎖,結果以下所示:
    db.currentOp()

數據備份、恢復與遷移管理

```sql

mongodump -h dbhost -d dbname -c collection -o dbdirectory
mongorestore -h dbhost -d dbname -c collection --directoryperdb dbdirectory

-- 備份所有數據庫
mkdir testbak
mongodump
-- 備份指定數據庫
mongodump -d pagedb
-- 備份一個數據庫中的某個集合
mongodump -d pagedb -c page
-- 恢復所有數據庫
cd testbak
mongorestore --drop
-- 恢復某個數據庫的數據
cd testbak
mongorestore -d pagedb --drop

-- 恢復某個數據庫的某個集合的數據
mongorestore -d pagedb -c page --drop
-- 向MongoDB導入數據
mongoimport -d pagedb -c page --type csv --headerline --drop < csvORtsvFile.csv
-- 將文件csvORtsvFile.csv的數據導入到pagedb數據庫的page集合中,使用cvs或tsv文件的列名做爲集合的列名。
-- 須要注意的是,使用--headerline選項時,只支持csv和tsv文件。
-- type支持的類型有三個:csv、tsv、json

MongoDB 監控

mongostat 
mongotop
mongotop 10   -- 等待時間
mongotop --locks  -- 報告每一個數據庫的鎖的使用

MongoDB 自動增加

MongoDB 沒有像 SQL 同樣有自動增加的功能, MongoDB 的 _id 是系統自動生成的12字節惟一標識。db.createCollection("counters"),經過db.counters.insert({_id:"productid",sequence_value:0}) 來實現

function getNextSequenceValue(sequenceName){
   var sequenceDocument = db.counters.findAndModify(
      {
         query:{_id: sequenceName },
         update: {$inc:{sequence_value:1}},
         new:true
      });
   return sequenceDocument.sequence_value;
}
db.products.insert({
       "_id":getNextSequenceValue("productid"),
       "product_name":"Apple iPhone",
       "category":"mobiles"
    })

    db.products.insert({
   "_id":getNextSequenceValue("productid"),
   "product_name":"Samsung S3",
   "category":"mobiles"})

   db.products.find()

關於ObjectId

前4個字節表示時間戳
接下來的3個字節是機器標識碼
緊接的兩個字節由進程id組成(PID)
最後三個字節是隨機數。

newObjectId = ObjectId()
    myObjectId = ObjectId("5349b4ddd2781d08c09890f4")
    ObjectId("5349b4ddd2781d08c09890f4").getTimestamp()

    new ObjectId().str

GridFS

GridFS 用於存儲和恢復那些超過16M(BSON文件限制)的文件(如:圖片、音頻、視頻等)。
GridFS 也是文件存儲的一種方式,可是它是存儲在MonoDB的集合中。
GridFS 能夠更好的存儲大於16M的文件。
GridFS 會將大文件對象分割成多個小的chunk(文件片斷),通常爲256k/個,每一個chunk將做爲MongoDB的一個文檔(document)被存儲在chunks集合中。
GridFS 用兩個集合來存儲一個文件:fs.filesfs.chunks

--fs.files
{
   "filename": "test.txt",
   "chunkSize": NumberInt(261120),
   "uploadDate": ISODate("2014-04-13T11:32:33.557Z"),
   "md5": "7b762939321e146569b07f72c62cca4f",
   "length": NumberInt(646)
}

-- fs.chunks
{
   "files_id": ObjectId("534a75d19f54bfec8a2fe44b"),
   "n": NumberInt(0),
   "data": "Mongo Binary Data"
}

-- 添加文件
mongofiles.exe -d gridfs put song.mp3
db.fs.files.find()

--_id 獲取區塊(chunk)
db.fs.chunks.find({files_id:ObjectId('534a811bf8b4aa4d33fdf94d')})
相關文章
相關標籤/搜索