MongoDB的經常使用用法

1 經過配置項啓動數據庫

1.1 準備配置文件

mongo.confjavascript

dbpath=/Users/**/Documents/**/mongodb/data
port=3000
複製代碼

1.2 啓動服務器

命令行輸入java

mongod --config mongo.conf
複製代碼

1.3 啓動客戶端

命令行輸入git

mongo --port 3000
複製代碼

2 導入導出數據

2.1 語法

  • 導入數據 mongoimport
  • 導出數據 mongoexport
參數 含義
-h [ --host ] 鏈接的數據庫
--port 端口號
-u 用戶名
-p 密碼
-d 導出的數據庫
-c 指定導出的集合
-o 導出的文件存儲路徑
-q 進行過濾

2.2 舉個栗子

2.2.1 數據庫中的原始數據

數據庫實例school下的grade1集合mongodb

{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abd6"), "name" : "Lucy_1", "age" : 1 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abd7"), "name" : "Lucy_2", "age" : 2 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abd8"), "name" : "Lucy_3", "age" : 3 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abd9"), "name" : "Lucy_4", "age" : 4 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abda"), "name" : "Lucy_5", "age" : 5 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abdb"), "name" : "Lucy_6", "age" : 6 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abdc"), "name" : "Lucy_7", "age" : 7 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abdd"), "name" : "Lucy_8", "age" : 8 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abde"), "name" : "Lucy_9", "age" : 9 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abdf"), "name" : "Lucy_10", "age" : 10 }
複製代碼

2.2.2 將原始數據導出

127.0.0.1host下的3000端口的school數據庫下的grade1集合中的數據導出到students.bak文件下數據庫

$ mongoexport -h 127.0.0.1 --port 3000 -d school -c grade1 -o students.bak
// 2018-05-03T21:20:17.838+0800 connected to: 127.0.0.1:3000
// 2018-05-03T21:20:17.844+0800 exported 10 records
複製代碼

2.2.3 刪除原始數據

  • 刪除數據
db.grade1.remove({})
// WriteResult({ "nRemoved" : 10 })
複製代碼
  • 檢查grade1集合是否已經被刪除-
db.grade1.count()
//0
複製代碼

2.2.4 導入以前的記錄

  • 導入
$ mongoimport -h 127.0.0.1 --port 3000 -d school -c grade1 --file students.bak
// 2018-05-03T21:33:20.503+0800 connected to: 127.0.0.1:3000
// 2018-05-03T21:33:20.512+0800 imported 10 documents
複製代碼
  • 檢查數據是否已經導入
db.grade1.find({})
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abd6"), "name" : "Lucy_1", "age" : 1 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abd9"), "name" : "Lucy_4", "age" : 4 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abd7"), "name" : "Lucy_2", "age" : 2 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abd8"), "name" : "Lucy_3", "age" : 3 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abda"), "name" : "Lucy_5", "age" : 5 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abdc"), "name" : "Lucy_7", "age" : 7 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abdb"), "name" : "Lucy_6", "age" : 6 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abdd"), "name" : "Lucy_8", "age" : 8 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abde"), "name" : "Lucy_9", "age" : 9 }
{ "_id" : ObjectId("5aeb05dc6cebbe7c6012abdf"), "name" : "Lucy_10", "age" : 10 }
複製代碼

3 備份與恢復

3.1 語法

備份(mongodump) + 恢復(mongorestore)json

3.1.1 備份

在Mongodb中咱們使用mongodump命令來備份MongoDB數據。該命令能夠導出全部數據到指定目錄中。數組

mongodump -h dbhost -d dbname -o dbdirectory
複製代碼
  • -h MongDB所在服務器地址,例如:127.0.0.1,固然也能夠指定端口號:127.0.0.1:27017
  • -d 須要備份的數據庫實例,例如:test
  • -o 備份的數據存放位置

3.1.2 恢復

mongodb使用 mongorestore 命令來恢復備份的數據。bash

  • 恢復數據庫全部的集合;
mongorestore -h dbhost --port 3000 data.bmp
複製代碼
  • 恢復數據庫中的某一個集合:
mongorestore -h dbhost --port 3000 data.bmp/dbname
複製代碼
  • --host MongoDB所在服務器地址
  • -d 須要恢復的數據庫實例
  • 最後的一個參數,設置備份數據所在位置

3.2 舉個栗子

3.2.1 備份

  • 命令行輸入
mongodump -h 127.0.0.1 --port 3000 -d school -o data.dmp

/* 2018-05-04T23:56:37.693+0800 writing school.grade3 to 2018-05-04T23:56:37.694+0800 writing school.grade1 to 2018-05-04T23:56:37.695+0800 writing school.grade2 to 2018-05-04T23:56:37.696+0800 done dumping school.grade3 (0 documents) 2018-05-04T23:56:37.697+0800 done dumping school.grade1 (9 documents) 2018-05-04T23:56:37.697+0800 done dumping school.grade2 (0 documents) */
複製代碼
  • 刪除數據
db.grade1.remove({})
// WriteResult({ "nRemoved" : 10 })
複製代碼
  • 檢查grade1集合是否已經被刪除
db.grade1.count()
//0
複製代碼

3.2.2 恢復

  • 命令行輸入
$ mongorestore -h 127.0.0.1 --port 3000 data.dmp

/* 2018-05-05T00:07:25.936+0800 preparing collections to restore from 2018-05-05T00:07:25.937+0800 reading metadata for school.grade1 from data.dmp/school/grade1.metadata.json 2018-05-05T00:07:25.937+0800 reading metadata for school.grade2 from data.dmp/school/grade2.metadata.json 2018-05-05T00:07:25.937+0800 reading metadata for school.grade3 from data.dmp/school/grade3.metadata.json 2018-05-05T00:07:25.937+0800 restoring school.grade1 from data.dmp/school/grade1.bson 2018-05-05T00:07:25.938+0800 restoring school.grade3 from data.dmp/school/grade3.bson 2018-05-05T00:07:25.938+0800 restoring school.grade2 from data.dmp/school/grade2.bson 2018-05-05T00:07:25.939+0800 no indexes to restore 2018-05-05T00:07:25.939+0800 finished restoring school.grade2 (0 documents) 2018-05-05T00:07:25.939+0800 no indexes to restore 2018-05-05T00:07:25.939+0800 finished restoring school.grade3 (0 documents) 2018-05-05T00:07:25.940+0800 no indexes to restore 2018-05-05T00:07:25.940+0800 finished restoring school.grade1 (10 documents) 2018-05-05T00:07:25.940+0800 done */
複製代碼

4 直接拷貝數據

最暴力最原始的方法,那就是直接拷貝~服務器

5 鎖定和解鎖數據庫

爲了數據的完整性和一致性,導出前要先鎖定寫入,導出後再解鎖。app

> use admin;
switched to db admin

// 鎖定
> db.runCommand({fsync:1,lock:1});
/*{ "info" : "now locked against writes, use db.fsyncUnlock() to unlock", "lockCount" : NumberLong(1), "seeAlso" : "http://dochub.mongodb.org/core/fsynccommand", "ok" : 1 }*/


// 已經被鎖定 寫入操做不能執行
> db.grade1.insert({name:'Lucy_3', age: 3})
// 沒有結果,等待中


// 解鎖
> db.fsyncUnlock()
//{ "info" : "fsyncUnlock completed", "lockCount" : NumberLong(0), "ok" : 1 }


// 解鎖後能夠正常進行寫入操做
> db.grade1.insert({name:'Lucy_3', age: 3})
// WriteResult({ "nInserted" : 1 })
複製代碼

6 用戶管理

  • 用戶的操做都須要在admin數據庫下面進行操做
  • 若是在某個數據庫下面執行操做,那麼只對當前數據庫生效

6.1 查看角色

show roles
 /* { "role" : "dbAdmin", "db" : "school", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } { "role" : "dbOwner", "db" : "school", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } { "role" : "enableSharding", "db" : "school", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } { "role" : "read", "db" : "school", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } { "role" : "readWrite", "db" : "school", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } { "role" : "userAdmin", "db" : "school", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } */
複製代碼

6.2 建立用戶

> db.createUser({user:'mytest', pwd:'123', roles:[{role:'readWrite', db: 'school'}, 'read']})

/* 添加一個 Successfully added user: { "user" : "mytest", "roles" : [// 用戶的權限配置 { "role" : "readWrite", "db" : "school" }, "read" ] }*/
複製代碼

6.3 查看用戶權限

>  db.runCommand({usersInfo:'mytest', showPrivileges: true})
/*{ "users" : [ { "_id" : "school.mytest", "user" : "mytest", "db" : "school", "roles" : [ { "role" : "readWrite", "db" : "school" }, { "role" : "read", "db" : "school" } ], "inheritedRoles" : [ { "role" : "read", "db" : "school" }, { "role" : "readWrite", "db" : "school" } ], "inheritedPrivileges" : [ ... ] } ], "ok" : 1 }*/
複製代碼

6.4 服務器啓動權限認證

添加了一個用戶以後,再從新啓動mongodb服務器並添加權限

// 添加--auth 參數
mongod --dbpath=./data --auth
複製代碼

6.5 用戶登陸和修改密碼

  • 驗證用戶權限

db.auth(username, password) 或者 db.auth({ user: username, pwd: password })

> db.auth('mytest', '123');
/* 驗證經過時: 1 */
/* 驗證不經過時: Error: Authentication failed. 0 */
複製代碼
  • 修改用戶名密碼

db.changeUserPassword(username, password)

> db.changeUserPassword('mytest', '456')

> db.auth('mytest', '456')
// 1
複製代碼

6.6 修改我的信息

> db.runCommand({updateUser:'mytest', pwd: '456',customData:{name:'測試'}})
// { "ok" : 1 }
複製代碼

添加的用戶信息能夠經過runCommand({usersInfo: 'mytest', showPrivileges: true})命令查看。

7 數據庫高級命令

7.1 distinct

7.1.1 做用

在單個集合中查找指定字段的不一樣值,即不重複的值。返回一個數組,數組包含的是不一樣的值。

7.1.2 語法

{
  distinct: "<collection>",
  key: "<field>",
  query: <query>,
  readConcern: <read concern document>,
  collation: <collation document>
}
複製代碼

7.1.3 舉個栗子

// 原始數據
{ "_id" : ObjectId("5af416dd7d5233c02aeb0058"), "name" : "Tom1", "age" : 2, "province" : "山東", "city" : "德州" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb0059"), "name" : "Tom2", "age" : 3, "province" : "山東", "city" : "青島" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb005a"), "name" : "Tom3", "age" : 3, "province" : "北京", "city" : "北京" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb005b"), "name" : "Tom4", "age" : 2, "province" : "山西", "city" : "大同" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb005c"), "name" : "Tom5", "age" : 1, "province" : "安徽", "city" : "合肥" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb005d"), "name" : "Tom6", "age" : 3, "province" : "安徽", "city" : "合肥" }
複製代碼
// 對 ‘grade2’集合進行操做,篩選條件爲 age > 2
> db.runCommand({distinct: 'grade2', key: 'province', query: {age: {$gt: 2}}})
// { "values" : [ "山東", "北京", "安徽" ], "ok" : 1 }
複製代碼

7.2 group分組

7.2.1 語法

db.runCommand({
        group:{
                ns:集合名稱,
                key:分組的鍵,
                initial:初始值,
                $reduce:分解器
                query:條件,
                finalize:完成時的處理器
        }
});
複製代碼

7.2.2 舉個栗子

// 原始數據
{ "_id" : ObjectId("5af416dd7d5233c02aeb0058"), "name" : "Tom1", "age" : 2, "province" : "山東", "city" : "德州" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb0059"), "name" : "Tom2", "age" : 3, "province" : "山東", "city" : "青島" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb005a"), "name" : "Tom3", "age" : 3, "province" : "北京", "city" : "北京" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb005b"), "name" : "Tom4", "age" : 2, "province" : "山西", "city" : "大同" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb005c"), "name" : "Tom5", "age" : 1, "province" : "安徽", "city" : "合肥" }
{ "_id" : ObjectId("5af416dd7d5233c02aeb005d"), "name" : "Tom6", "age" : 3, "province" : "安徽", "city" : "合肥" }
複製代碼
  • 根據省份進行分組 (篩選條件爲 age > 1
db.runCommand({
    group: {
        ns: 'grade2',
        key: {
            province: 1
        },
        initial: {
            total: 0
        },
        $reduce: function(doc, result) {
            result.total += doc.age;
        },
        query: {
            age: {
                $gt: 1
            }
        },
        finalize: function(result) {
            result.output = '年齡總和爲: ' + result.total
        }
    }
})

// 運行結果爲:共處理 5(count)條數據,分爲 4 組
{
	"retval" : [
		{
			"province" : "山東",
			"total" : 5,
			"output" : "年齡總和爲: 5"
		},
		{
			"province" : "北京",
			"total" : 3,
			"output" : "年齡總和爲: 3"
		},
		{
			"province" : "山西",
			"total" : 2,
			"output" : "年齡總和爲: 2"
		},
		{
			"province" : "安徽",
			"total" : 3,
			"output" : "年齡總和爲: 3"
		}
	],
	"count" : NumberLong(5),
	"keys" : NumberLong(4),
	"ok" : 1
}
複製代碼
  • 根據 省份 + 城市 進行分組(篩選條件爲 age > 1
// 運行命令
db.runCommand({
    group: {
        ns: 'grade2',
        key: {
            province: 1,
            city: 1
        },
        initial: {
            total: 0
        },
        $reduce: function(doc, result) {
            result.total += doc.age;
        },
        query: {
            age: {
                $gt: 1
            }
        }
    }
})

// 運行結果爲:共處理 5 條數據,分爲 5 組
{
	"retval" : [
		{
			"province" : "山東",
			"city" : "德州",
			"total" : 2
		},
		{
			"province" : "山東",
			"city" : "青島",
			"total" : 3
		},
		{
			"province" : "北京",
			"city" : "北京",
			"total" : 3
		},
		{
			"province" : "山西",
			"city" : "大同",
			"total" : 2
		},
		{
			"province" : "安徽",
			"city" : "合肥",
			"total" : 3
		}
	],
	"count" : NumberLong(5),
	"keys" : NumberLong(5),
	"ok" : 1
}
複製代碼

7.3 drop 刪除集合

  • 語法
db.runCommand({
    drop: 集合名稱
})
複製代碼
  • 舉個栗子
> show collections
/* grade1 grade2 grade3 */

// 刪除 grade3 集合
> db.runCommand({drop: 'grade3'})
// { "ns" : "school.grade3", "nIndexesWas" : 1, "ok" : 1 }

> show collections
/*grade1 grade2*/
複製代碼

7.4 db.runCommand() 經常使用命令

  • buildInfo - 返回當前mongd 的構建摘要
> db.runCommand({buildInfo: 1})
/*{ "version" : "3.4.7", "gitVersion" : "cf38c1b8a0a8dca4a11737581beafef4fe120bcd", "modules" : [ ], "allocator" : "system", "javascriptEngine" : "mozjs", ... "ok" : 1 }*/
複製代碼
  • getLastError - 獲取前一次的錯誤信息
> db.grade1.insert({name: 'Lucy_4', age: 4, _id: 1})
//WriteResult({ "nInserted" : 1 })

> db.grade1.insert({name: 'Lucy_4', age: 4, _id: 1})
/* 報錯: WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error collection: school.grade1 index: _id_ dup key: { : 1.0 }" } })*/

> db.runCommand({getLastError: 'school'})
/* 捕獲到前一次的錯誤信息 { "connectionId" : 1, "err" : "E11000 duplicate key error collection: school.grade1 index: _id_ dup key: { : 1.0 }", "code" : 11000, "codeName" : "DuplicateKey", "n" : 0, "ok" : 1 }*/
>
複製代碼

8 固定集合

MongoDB 固定集合(Capped Collections)是性能出色且有着固定大小的集合,對於大小固定,咱們能夠想象其就像一個環形隊列,當集合空間用完後,再插入的元素就會覆蓋最初始的頭部元素。

形狀以下圖:

固定集合

8.1 特性

  • 沒有索引
  • 插入和查詢速度速度很是快 不須要從新分配空間
  • 特別適合存儲日誌

8.2 建立固定集合

  • 經過createCollection來建立一個固定集合,且capped選項設置爲true:
db.createCollection('logs', {
    size: 5,      // 整個集合空間大小,單位爲【KB】
    max: 3,       // 集合文檔個數上線,單位是【個】
    capped: true    // 設置爲true, 表示建立的是固定集合
})
複製代碼
  • 若是空間大小到達上限,則插入下一個文檔時,會覆蓋第一個文檔;若是文檔個數到達上限,一樣插入下一個文檔時,會覆蓋第一個文檔。兩個參數上限判斷取的是【與】的邏輯。
> db.logs.insert([{time: 1}, {time: 2}, {time: 3}, {time: 4}])

> db.logs.find({})
/* { "_id" : ObjectId("5af441247d5233c02aeb0061"), "time" : 2 } { "_id" : ObjectId("5af441617d5233c02aeb0062"), "time" : 3 } { "_id" : ObjectId("5af441687d5233c02aeb0063"), "time" : 4 } */
複製代碼
  • 判斷集合是否爲固定集合: db.logs.isCapped()
> db.logs.isCapped()
// true
> db.grade1.isCapped()
// false
複製代碼

8.3 非固定集合轉爲固定集合

db.runCommand({convertToCapped: 'logs', size: 6})
// { "ok" : 1 }
複製代碼

9 gridfs

9.1 介紹

  • gridfs是mongodb自帶的文件系統,使用二進制存儲文件。
  • mongodb能夠以BSON格式保存二進制對象。
  • 可是BSON對象的體積不能超過4M。因此mongodb提供了mongofiles。它能夠把一個大文件透明地分割成小文件(256K),從而保存大致積的數據。
  • GridFS 用於存儲和恢復那些超過16M(BSON文件限制)的文件(如:圖片、音頻、視頻等)。
  • GridFS 用兩個集合來存儲一個文件:fs.files與fs.chunks。
  • 每一個文件的實際內容被存在chunks(二進制數據)中,和文件有關的meta數據(filename,content_type,還有用戶自定義的屬性)將會被存在files集合中。

9.2 文件操做

9.2.1 上傳文件 put

mongofiles -d dbname put 文件名
複製代碼
> mongofiles --port 3000 -d myfiles put 1.txt
/* 2018-05-10T21:14:50.170+0800 connected to: localhost:3000 added file: 1.txt */

// 會生成兩個集合
> show collections
/* fs.chunks fs.files */


// fs.files 存儲的doc
{
    "_id" : ObjectId("5af445cac3666e928f286c5a"),
    "chunkSize" : 261120,
    "uploadDate" : ISODate("2018-05-10T13:14:50.203Z"),
    "length" : 12,
    "md5" : "a2ef74a76b2bfcfe14817a27c511759c",
    "filename" : "1.txt"
}


// fs.chunks 存儲的 doc
{
    "_id" : ObjectId("5af445cac3666e928f286c5b"),
    "files_id" : ObjectId("5af445cac3666e928f286c5a"),
    "n" : 0,
    "data" : { "$binary" : "MTIzCjQ1Ngo3ODkK", "$type" : "00" }
}

複製代碼
  • 若是上傳一個大文件的時候,會分爲多個chunks 存儲
// (bigFile.zip 大小爲 85.6MB)
> mongofiles --port 3000 -d myfiles put bigFile.zip
/* 2018-05-10T21:29:23.425+0800 connected to: localhost:3000 added file: bigFile.zip */

// 1.txt 和 bigFile.zip 總共佔用了 333 個網格
> db.fs.chunks.count()
333
複製代碼

9.2.2 下載文件 get

> mongofiles --port 3000 -d myfiles get 1.txt
/* 2018-05-10T21:36:24.889+0800 connected to: localhost:3000 finished writing to 1.txt */
複製代碼

9.2.3 查看全部文件 list

> mongofiles --port 3000 -d myfiles list
/* 2018-05-10T21:37:21.424+0800 connected to: localhost:3000 1.txt 12 bigFile.zip 86493501 */
複製代碼

9.2.4 刪除文件 delete

> mongofiles --port 3000 -d myfiles delete 1.txt
/* 2018-05-10T21:38:42.324+0800 connected to: localhost:3000 successfully deleted all instances of '1.txt' from GridFS */
複製代碼

9.3 eval 服務器端腳本

  • 執行JS語句
  • 定義JS全局變量
  • 定義函數
  • Stored JavaScript
// 執行JS語句
> db.eval("return 'hello'");
WARNING: db.eval is deprecated
hello

// 定義JS全局變量
> db.system.js.insert({_id:'myname', value: 'Lily'})
// WriteResult({ "nInserted" : 1 })
> db.eval("return myname");
/* WARNING: db.eval is deprecated Lily */


// 定義函數
> db.system.js.insert({_id:'sayHello', value: function(){return 'hello'}})
// WriteResult({ "nInserted" : 1 })

> db.eval("sayHello()");
/* WARNING: db.eval is deprecated hello */
複製代碼

定義的函數在客戶端的顯示以下圖:

function
相關文章
相關標籤/搜索