感謝 Karl Seguin 編寫的 The Little MongoDB Book 這本 MongoDB 入門書。javascript
本文內容主要來自「The Little MongoDB Book」的學習,學習筆記基於我的理解對原書部份內容進行調整。html
若是你是 MongoDB 數據庫初學者,建議從學習「The Little MongoDB Book」 開始。java
若是須要練習 MongoDB 相關命令行工具可直接閱讀本學習筆記。git
筆者測試 MongoDB 數據庫版本較早,但文中涉及的全部 MongoDB 概念及命令行工具基本適用於全部版本。github
瞭解 MongoDB 前先了解 NoSQL,NoSQL 是一種數據存儲系統(非關係型數據庫系統),相比 MySQL 這類關係型數據庫提供通用的數據存儲解決方案,NoSQL 傾向負責解決系統中一部分數據存儲問題。算法
MongoDB 是一種 NoSQL 解決方案,提供更加通用的 NoSQL 方案。mongodb
本文約定 Mongo 和 MongoDB 都是代指 MongoDB 數據庫系統。shell
在學習 MongoDB 以前,須要安裝 MongoDB 環境。可到 官方下載頁面 下載須要的 MongoDB 版本。數據庫
dbpath=PATH_TO_WHERE_YOU_WANT_TO_STORE_YOUR_DATABASE_FILES
例如,在 Windows 中您須要添加的多是 dbpath=c:\mongodb\data,而在Linux下可能就是 dbpath=/etc/mongodb/data。數組
上面的安裝步驟用於安裝和啓動 MongoDB 服務器進程。下面以 Windows 系統爲例,講解 MongoDB 安裝及啓動詳細過程。
對於不建立 c:\mongodb\bin\mongodb.config配置的用戶,能夠經過 --dbpath 參數啓動服務,執行 c:\mongodb\bin\mongod --dbpath c:\mongodb\data\;效果和使用 --config 參數同樣。
接下來,咱們經過 SHELL 環境鏈接 MongoDB 服務。進入 c:\mongodb\bin 目錄,執行 mongo 命令,便可完成 MongoDB 服務鏈接。
須要說明的是 MongoDB 在 c:\mongodb\bin,提供了一些工具,其中就包括上去的 mongod.exe 和 mongo.exe,它們對應 mongod 和 mongo 命令。
若是有使用過關係型數據庫(如 MySQL),那麼對數據庫、表、行、字段這些概念不會陌生,在 MongoDB 中也有相似的數據結構,不過在 Mongo 中將以另外一種形式存在:
MongoDB 和 關係型數據庫相關概念關係對照表:
SQL術語/概念 | MongoDB術語/概念 | 解釋/說明 |
---|---|---|
database | database | 數據庫 |
table | collection | 數據庫表/集合 |
row | document | 數據記錄行/文檔 |
column | field | 數據字段/域 |
index | index | 索引 |
table joins | 錶鏈接,MongoDB不支持 | |
primary key | primary key | 主鍵,MongoDB自動將_id字段設置爲主鍵 |
表格信息引用自 MongoDB 概念解析
下文中全部命令,需在命令終端執行。當使用 mongo 命令成功鏈接 MongoDB 服務後,可使用 help 獲取 MongoDB 數據庫使用幫助,它的執行結果大體以下:
> help db.help() help on db methods db.mycoll.help() help on collection methods rs.help() help on replica set methods help admin administrative help help connect connecting to a db help help keys key shortcuts help misc misc things to know help mr mapreduce show dbs show database names show collections show collections in current database show users show users in current database show profile show most recent system.profile entries with time >= 1ms show logs show the accessible logger names show log [name] prints out the last segment of log in memory, 'global' is default use <db_name> set current database db.foo.find() list objects in collection foo db.foo.find( { a : 1 } ) list objects in foo where a == 1 it result of the last line evaluated; use to further iterate DBQuery.shellBatchSize = x set default number of items to display on shell exit quit the mongo shell
1 顯示 MongoDB 數據庫
執行 show dbs,顯示 MongoDB 全部數據庫
2 切換 MongoDB 數據庫
執行 use test,將工做數據庫切入到 test 數據庫。在 MongoDB 中沒有相似關係數據庫的 Schema 概念,因此即便 MongoDB 的數據庫未建立,也能夠任意切換工做數據庫。
3 顯示數據庫中的集合(collection)
執行 show colections,會打印輸出當前數據庫中的全部數據庫集合。
4 獲取工做數據庫幫助信息
當使用 use test 進入 test 數據庫後,能夠執行 db.help() 指令查看 database 級別支持的命令,結果以下:
> db.help() DB methods: db.addUser(username, password[, readOnly=false]) db.auth(username, password) db.cloneDatabase(fromhost) db.commandHelp(name) returns the help for the command db.copyDatabase(fromdb, todb, fromhost) db.createCollection(name, { size : ..., capped : ..., max : ... } ) db.currentOp() displays the current operation in the db db.dropDatabase() db.eval(func, args) run code server-side db.getCollection(cname) same as db['cname'] or db.cname db.getCollectionNames() db.getLastError() - just returns the err msg string db.getLastErrorObj() - return full status object db.getMongo() get the server connection object db.getMongo().setSlaveOk() allow this connection to read from the nonmaster member of a replica pair db.getName() db.getPrevError() db.getProfilingLevel() - deprecated db.getProfilingStatus() - returns if profiling is on and slow threshold db.getReplicationInfo() db.getSiblingDB(name) get the db at the same server as this one db.isMaster() check replica primary status db.killOp(opid) kills the current operation in the db db.listCommands() lists all the db commands db.logout() db.printCollectionStats() db.printReplicationInfo() db.printSlaveReplicationInfo() db.printShardingStatus() db.removeUser(username) db.repairDatabase() db.resetError() db.runCommand(cmdObj) run a database command. if cmdObj is a string, turns it into { cmdObj : 1 } db.serverStatus() db.setProfilingLevel(level,<slowms>) 0=off 1=slow 2=all db.shutdownServer() db.stats() db.version() current version of the server db.getMongo().setSlaveOk() allow queries on a replication slave server db.fsyncLock() flush data to disk and lock server for backups db.fsyncUnock() unlocks server following a db.fsyncLock()
5 查看工做數據庫名
須要查看當前工做的數據庫,執行以下命令
> db.getName() test1
6 查看工做數據庫統計信息
db.stats() 會列出工做數據庫中 集合、數據庫大小等有用的信息。
> db.stats() { "db":"test", --查看的是哪一個數據庫 "collections":7, --collection數量 "objects":28, --對象數量 "avgObjSize":50.57142857142857, --對象平均大小 "dataSize":1416, --數據大小 "storageSize":31744, --數據大小(含預分配空間) "numExtents":7, --事件數量 "indexes":7, --索引數量 "indexSize":57344, --索引大小 "fileSize":50331648, --文件大小 "ok":1 --本次取stats是否正常 }
上例結果引用自 db.stats() - 顯示當前db狀態
7 刪除數據庫
當須要刪除 某個 數據庫時,請先使用 use 指令切換工做數據庫至待刪除數據庫。而後執行 db.dropDatabase() 指令。
> show dbs local (empty) test 0.03125GB test1 (empty) > use test1 switched to db test1 > db.dropDatabase() { "dropped" : "test1", "ok" : 1 } > show dbs local (empty) test 0.03125GB
有了上面的基本概念,咱們就知道如何使用 MongoDB 的數據庫和數據集了,下面是一個小練習,來加深相關知識的使用及理解:
場景:咱們開闢一個訓練場,將完成數據庫服務啓動、客戶端鏈接 MongoDB 服務、查看和選擇數據庫及數據庫刪除操做。
約定在 shell 中以 -- 開始的註釋說明信息:執行時請不要賦值註釋信息。
-- 1. 啓動一個 Windows 命令行窗口,開啓 MongoDB 服務 > cd c:\mongodb\bin > mongod --config c:\mongodb\bin\mongodb.config -- 2. 另啓動一個 Windows 命令行窗口鏈接 MongoDB 服務 > cd c:\mongodb\bin > mongo MongoDB shell version: 2.0.7 connecting to: test -- 3. 查看全部數據庫 > show dbs local (empty) test 0.03125GB test1 (empty) -- 4. 切換工做數據庫至 blog > use blog switched to db blog -- 5. 查看當前工做數據庫 > db.getName() blog -- 6. 切換工做數據庫至 test > use test switched to db test -- 7. 查看當前工做數據庫 > db.getName() test -- 8. 切回工做數據庫至 blog > use blog switched to db blog -- 9. 查看 blog 庫的全部集合, 因爲是空數據庫因此會沒有返回信息 > show collections -- 10 查看 blog 庫的狀態,因爲是空數據庫因此統計信息內相關數據爲空 > db.stats() { "db" : "blog", "collections" : 0, "objects" : 0, "avgObjSize" : 0, "dataSize" : 0, "storageSize" : 0, "numExtents" : 0, "indexes" : 0, "indexSize" : 0, "fileSize" : 0, "nsSizeMB" : 0, "ok" : 1 } -- 11. 插入一個用戶到 blog 數據庫的 user 集合裏。 -- 不知道如何插入?不要緊,直接複製下面的命令就行了。 > db.user.insert({name: 'huliuqing', age: 18, hobby: ['coding', 'reading']}) -- 12. 查看剛剛 user 集合的插入結果 > db.user.find() { "_id" : ObjectId("5abde35e7d318c10d73539e3"), "name" : "huliuqing", "age" : 18, "hobby" : [ "coding", "reading" ] } -- 13. 再看下 blog 庫的狀態 > db.stats() { "db" : "blog", "collections" : 3, "objects" : 5, "avgObjSize" : 51.2, "dataSize" : 256, "storageSize" : 16384, "numExtents" : 3, "indexes" : 1, "indexSize" : 8176, "fileSize" : 16777216, "nsSizeMB" : 16, "ok" : 1 } -- 14. 刪除 user 集合 -- 不知道使用什麼命令?那先來查看下 user 集合層級的幫助信息吧 > db.user.help() ... db.user.drop() drop the collection ... > db.user.drop() true -- 14. 再看下 blog 庫的狀態 { "db" : "blog", "collections" : 2, "objects" : 1, "avgObjSize" : 36, "dataSize" : 36, "storageSize" : 8192, "numExtents" : 2, "indexes" : 0, "indexSize" : 0, "fileSize" : 16777216, "nsSizeMB" : 16, "ok" : 1 } -- 15. 刪除 blog 數據庫 > db.dropDatabases() { "dropped" : "blog", "ok" : 1 } -- 16. 再看下 blog 庫的狀態 > db.stats() { "db" : "blog", "collections" : 0, "objects" : 0, "avgObjSize" : 0, "dataSize" : 0, "storageSize" : 0, "numExtents" : 0, "indexes" : 0, "indexSize" : 0, "fileSize" : 0, "nsSizeMB" : 0, "ok" : 1 } -- 17 查看下數據庫 > show dbs local (empty) test 0.03125GB test1 (empty)
另外須要說明的是 MongoDB 的 SHELL 運行於 JavaScript 之上。除全局命令外,操做 db 數據庫、 db.COLLECTION_NAME 操做集合,若缺乏 () 將會在 SHELL 裏打印出方法的實現源碼。
前面咱們學習瞭如何使用 MongoDB 的幫助,接下來在學習 CRUD 操做以前,進一步瞭解下 MongoDB 的數據庫及集合是如何建立的。
MongoDB 是 無模式 的,當使用 use YOUR_DATABASE 命令切換數據庫時,咱們無需預先建立 YOUR_DATABASE 數據庫,而當向某個 集合 插入一個 文檔 時,將會自動生成具體的數據庫、集合和文檔。
如:
> use mongo_playground > db.users.insert({name: 'huliuqing', age: 18, gender: 'male'})
上面的命令對 users 集合作 insert(插入文檔) 操做,傳入的參數是一個 JSON 格式數據。經過 show collections 命令查看到有: users 和 system.indexes 兩個集合存在,其中 system.indexes 集合會在每一個 數據庫 由 MongoDB 自主建立,這個集合包含數據庫中的索引信息。
在執行 insert 命令時,MongoDB 會生成一個值爲 ObjectId 類型的 _id 域。_id 域 對每一個 文檔 都是必須的,它相似於 SQL 的主鍵,咱們可使用本身的算法生成 _id 的值,大部分狀況下使用 MongoDB 的默認值就能夠了。
前面說過 _id 域 相似主鍵,它的索引信息被存儲在 system.indexes 集合內,咱們看看兩個集合裏有什麼數據:
-- 1. 查看集合 > show collections system.indexes users -- 2. 查看 users 集合數據 > db.users.find().pretty() { "_id" : ObjectId("5ac2f7ecfdcd54e4d368bde5"), "name" : "huliuqing", "age" : 18, "gender" : "male" } -- 3. 查看 system.indexes 集合數據 > db.system.indexes.find().pretty() { "v" : 1, "key" : { "_id" : 1 }, "ns" : "mongo_playground.users", "name" : "_id_" }
從結果咱們能夠看到 users 集合比添加的 JSON 多了 _id 域,它的索引信息被 system.indexes 集合記錄。
建立一個 文檔 由 db.YOUR_COLLECTION.insert() 命令完成,咱們向 db.users 集合插入一條新的文檔:
-- 1. 建立文檔 > db.users.insert({name: 'zhangsanfeng', age: 120, gender: 'male', hobby: ['Kung fu', 'Tai Chi']}); -- 2. 查詢結果 > db.users.find() { "_id" : ObjectId("5ac2f7ecfdcd54e4d368bde5"), "name" : "huliuqing", "age" : 18, "gender" : "male" } { "_id" : ObjectId("5ac3165bfdcd54e4d368bde6"), "name" : "zhangsanfeng", "age" : 120, "gender" : "male", "hobby" : [ "Kung fu", "Tai Chi" ] }
一個簡單的查詢操做可使用 db.YOUR_COLLECTION.find() 指令來獲取全部 YOUR_COLLECTION 集合的全部文檔列表。除此以外,咱們還須要知道在 MongoDB 中有個 查詢構造器 的概念,查詢構造器 相似於 SQL 中的 WHERE 語句
在學習查詢構造器以前,咱們先清洗下 mongo_playground 數據庫,並加入測試集合。
-- 1. 進入 mongo_playground 數據庫 > use mongo_playground -- 2. 刪除 mongo_playground 數據庫 > db.dropDatabase() -- 3. 建立測試數據 db.users.insert({name: 'Bob',birthday: new Date(1992,2,13,7,47),hobby: ['basketball','football'],weight: 60,gender: 'm',age: 18}); db.users.insert({name: 'John',birthday: new Date(1991, 0, 24, 13, 0),hobby: ['basketball', 'ping pong'],weight: 45,gender: 'm',age: 23}); db.users.insert({name: 'Tony',birthday: new Date(1973, 1, 9, 22, 10),hobby: ['boxing', 'racing'],weight: 98,gender: 'm',age: 30}); db.users.insert({name: 'Lily',birthday: new Date(1997, 6, 1, 10, 42),hobby: ['ping pong', 'yoga'],weight: 69,gender: 'f',age: 39}); db.users.insert({name: 'Jack',birthday: new Date(1979, 7, 18, 18, 44),hobby: ['skiing'],weight: 57,gender: 'm',age: 51}); db.users.insert({name: 'Tom',birthday: new Date(1985, 6, 4, 2, 1),hobby:['skiing', 'basketball','boxing'],weight:65,gender:'m',age:29}); db.users.insert({name: 'Jackson',birthday: new Date(1998, 2, 7, 8, 30),hobby: ['skateboard', 'running'],weight: 73,gender: 'f',age: 41}); db.users.insert({name: 'Lucy',birthday: new Date(2005, 4, 3, 0, 57),hobby: ['skiing', 'yoga'],weight: 42,gender: 'f',age: 22}); db.users.insert({name: 'Peter',birthday: new Date(2001, 9, 8, 14, 53),hobby: ['shooting', 'darts'],weight: 60,gender: 'm',age: 48}); db.users.insert({name: 'Rose',birthday: new Date(1997, 2, 1, 5, 3),hobby: ['shooting', 'darts'],weight: 65,gender: 'f',age: 56}); db.users.insert({name: 'Lee',birthday: new Date(1999, 11, 20, 16, 15),hobby: ['ping pong', 'basketball'],weight: 54,gender: 'm'});
查找用戶 name 等於 Lee 的信息
> db.users.find({name: 'Lee'}).pretty() { "_id" : ObjectId("5ac31e00fdcd54e4d368bdfc"), "name" : "Lee", "birthday" : ISODate("1999-12-20T08:15:00Z"), "hobby" : [ "ping pong", "basketball" ], "weight" : 54, "gender" : "m" }
查找喜歡 跑步 的 男性
> db.users.find({gender: 'm', hobby: 'racing'}).pretty() { "_id" : ObjectId("5ac31e00fdcd54e4d368bdf4"), "name" : "Tony", "birthday" : ISODate("1973-02-09T14:10:00Z"), "hobby" : [ "boxing", "racing" ], "weight" : 98, "gender" : "m", "age" : 30 }
查找喜歡 乒乓球 或 瑜伽 的 男性
-- 1. 僅查找喜歡 乒乓球 或 瑜伽 的用戶 > db.users.find({gender: 'm', $or: [{hobby: 'ping pong'}, {hobby: 'yoga'}]}) { "_id" : ObjectId("5ac327edfdcd54e4d368be09"), "name" : "John", "birthday" : ISODate("1991-01-24T05:00:00Z"), "hobby" : [ "basketball", "ping pong" ], "weight" : 45, "gender" : "m", "age" : 23 } { "_id" : ObjectId("5ac327edfdcd54e4d368be12"), "name" : "Lee", "birthday" : ISODate("1999-12-20T08:15:00Z"), "hobby" : [ "ping pong", "basketball" ], "weight" : 54, "gender" : "m" } -- 2. 下面的查找將查找到全部的喜歡 乒乓球 或 瑜伽 的用戶 > db.users.find({$or: [{hobby: 'ping pong'}, {hobby: 'yoga'}]})
經過 $lt(less than: 小於)**、**$lte(less than and equal: 小於等於)、$gt(greater than: 大於)**、**$gte(greater than and equal: 大於等於) 和 $ne(not equal: 不等於) 等實現比較查詢。
-- 1. 查詢年齡大於等於 30 歲且小於 40 歲的用戶 > db.users.find({age: {$gte: 30, $lt: 40}}) -- 2. 查詢年齡大於 55 歲的用戶 > db.users.find({age: {$gt: 55}}) -- 3. 查詢年齡小於 18 歲的用戶 > db.users.find({age: {$lt: 20}}) -- 4. 查詢年齡不等於 18 歲的用戶 > db.users.find({age: {$ne: 18}})
在 3.2.1.4 的第 4 個示例 4. 查詢年齡不等於 18 歲的用戶 會查詢到沒有 age 域的用戶 Lee。經過 $exists 指令能夠判斷某個域是否存在,它的值是 bool 類型,咱們對這個示例作些改進:
-- 1. 查詢年齡字段存在且年齡不等於 18 歲的用戶 > db.users.find({age: {$ne: 18, $exists: true}})
本章瞭解了 MongoDB 相關查詢操做,瞭解更多查詢命令細節能夠查看 查詢文檔。但更重要的是反覆練習這些查詢語句的基本用法。
MongoDB 的更新須要特別關注一下,更新數據使用 db.YOUR_COLLECTIONS.update(query, object, options) 方法,update 接收兩個必選參數:查詢選擇器 和 須要更新的域。
一個簡單的示例,咱們找到 年齡 48 歲 的用戶 Peter,將他的年齡 更新爲 49 歲。
> db.users.find({age: 48}).pretty() { "_id" : ObjectId("5ac42ff514c16270040db426"), "name" : "Peter", "birthday" : ISODate("2001-10-08T06:53:00Z"), "hobby" : [ "shooting", "darts" ], "weight" : 60, "gender" : "m", "age" : 48 } > db.users.update({age: 48}, {age: 49}) > db.users.find({age: 49}).pretty() { "_id" : ObjectId("5ac42ff514c16270040db426"), "age" : 49 }
再次查找 年齡 49 歲 的用戶,會發現 更新後 Perter 用戶數據被 覆蓋 爲 { "_id" : ObjectId("5ac42ff514c16270040db426"), "age" : 49 }(由於 ObjectId 相同)。
這是由於: 在 MongoDB 中接收的第二個參數,若是沒有使用 $set 修飾符,將會採起 覆蓋 文檔操做,而不是 更新文檔指定域,這和 SQL 的 UPDATE 語句行爲不同。
正確的更新 應該是下面的 update 寫法使用 {$set: {age: 49}},操做以前咱們要清空並重建測試數據。
> db.users.find({age: 48}).pretty() { "_id" : ObjectId("5ac42ff514c16270040db426"), "name" : "Peter", "birthday" : ISODate("2001-10-08T06:53:00Z"), "hobby" : [ "shooting", "darts" ], "weight" : 60, "gender" : "m", "age" : 48 } > db.users.update({age: 48}, {$set: {age: 49}}) > db.users.find({age: 49}).pretty() { "_id" : ObjectId("5ac4375b14c16270040db43c"), "name" : "Peter", "birthday" : ISODate("2001-10-08T06:53:00Z"), "hobby" : [ "shooting", "darts" ], "weight" : 60, "gender" : "m", "age" : 49 }
建議: 在執行 刪除、更新 這類操做前,建議先採用相同的查詢條件查找數據,結果與判斷一致時再作 刪除、更新 等操做。
-- 1. Peter 又長大了一歲 > db.users.find({name: 'Peter'}) { "_id" : ObjectId("5ac4375b14c16270040db43c"), "name" : "Peter", "birthday" : ISODate("2001-10-08T06:53:00Z"), "hobby" : [ "shooting", "darts" ], "weight" : 60, "gender" : "m", "age" : 49 } > db.users.update({name: 'Peter'}, {$inc: {age: 1}}) -- 2. Peter 越活越年輕 > db.users.find({name: 'Peter'}) { "_id" : ObjectId("5ac4375b14c16270040db43c"), "name" : "Peter", "birthday" : ISODate("2001-10-08T06:53:00Z"), "hobby" : [ "shooting", "darts" ], "weight" : 60, "gender" : "m", "age" : 50 } > db.users.update({name: 'Peter'}, {$inc: {age: -5}}) -- 3. 由於 Peter 有了更多的興趣愛好 > db.users.update({name: 'Peter'}, {$push: {hobby: 'racing'}}) { "_id" : ObjectId("5ac4375b14c16270040db43c"), "age" : 45, "birthday" : ISODate("2001-10-08T06:53:00Z"), "gender" : "m", "hobby" : [ "shooting", "darts", "racing" ], "name" : "Peter", "weight" : 60 }
MongoDB update 方法第三個參數接收 bool 值的標識符,該值默認爲 false。當該值設爲 true 時若 查詢選擇器 的目標文檔存在,則採起 update $set 域 操做;若不存在則採起 INSERT 操做。
這個選項在相似 網站點擊計數器 統計場景中很是有用。若是網頁點擊記錄存在則更新記錄數,不存在則執行插入操做。
-- 1. 給 users 頁面統計點擊數, update 第三個參數爲 false 或 缺省,將不會建立 hits 集合 > db.hits.update({page: 'users'}, {$inc: {hits: 1}}) > db.hits.find() -- 2. upsert 選項設置爲 true,在執行 update 更新操做時,hits 集合未建立,執行建立操做 > db.hits.update({page: 'users'}, {$inc: {hits: 1}}, {upsert: true}) > db.hits.find() { "_id" : ObjectId("5ac4427bb5b4350bc6d2f715"), "hits" : 1, "page" : "users" } -- 3. upsert 選項設置爲 true,在執行 update 更新操做時,hits 集合已建立,執行更新操做 > db.hits.update({page: 'users'}, {$inc: {hits: 1}}, {upsert: true}) > db.hits.find() { "_id" : ObjectId("5ac4427bb5b4350bc6d2f715"), "hits" : 2, "page" : "users" }
MongoDB update 操做在 3.3.1 介紹過,更新數據須要 $set 修飾符,不然執行覆蓋操做。這裏咱們介紹它的第二個獨特特性:默認更新一條記錄。
當咱們須要給全部用戶加上點贊數 likes 域用於記錄用戶獲得的贊,咱們會想下面的方法同樣執行,但僅僅只有一條文檔加上了 likes 域:
> db.users.update({}, {$set:{likes: 0}}) > db.users.find({likes: 0})
multi 選項值設爲 true 能夠實現全部文檔記錄新增 域 操做。
> db.users.update({}, {$set:{likes: 0}}, false, true) > db.users.find({likes: 0})
能夠在文檔查看 update 方法相關具體使用。
經過 db.YOUR_COLLECTION.remove(query, justOne) 能夠刪除一個或全部 文檔,參數接收的查詢選擇器爲空時刪除全部文檔,當 justOne 標識爲 true 是僅刪除一條匹配文檔。
-- 1. 刪除用戶 Bob 的記錄 > db.users.find({name: 'Bob'}) > db.users.remove({name: 'Bob'}) > db.users.find({name: 'Bob'}) -- 2. 刪除全部用戶 > db.users.find() > db.users.remove() > db.users.find()
相關細節能夠查閱 刪除文檔。
若是須要刪除全部文檔,咱們還能夠經過 db.YOUR_COLLECTIONS.drop() 方法實現,drop() 方法不只刪除全部文檔還會刪除該集合的索引信息。
咱們在 3.2 章節中瞭解了有關 MongoDB 的查詢功能。本節咱們將學習包括查詢指定域、排序、返回的結果集記錄數限制和分頁等功能,這些方法在應用程序開發過程當中會十分常見。
在 Mongo Shell 裏咱們經過 db.YOUR_COLLECTION.find 注意 無 () 能夠看到 find 方法的具體實現,find 一共能夠接收 4 個參數:第一個參數是查詢選擇器;第二個參數即爲指定返回的域。
以前,咱們都是返會全部的域信息,如今讓咱們僅返回用戶的用戶名、年齡和性別:
> db.users.find({}, {name: true, age: true, gender: true}) { "_id" : ObjectId("5acada245c193d1acc967575"), "name" : "Bob", "gender" : "m", "age" : 18 } { "_id" : ObjectId("5acada245c193d1acc967576"), "name" : "John", "gender" : "m", "age" : 23 } { "_id" : ObjectId("5acada245c193d1acc967577"), "name" : "Tony", "gender" : "m", "age" : 30 } ...
默認 _id 域總會做爲查詢結果返回,能夠設置 {_id: falsee} 顯示的排除掉。
在 MongoDB 中咱們還須要瞭解一個基本概念 遊標(cursor),因爲前面咱們並無涉及到遊標的使用(只是看起來沒有涉及到遊標)。
find 方法返回的結果即爲依據查詢選擇器匹配到的文檔集合的 遊標,這樣能夠經過鏈式操做對 find 結果集進行處理。
咱們在 MongoDB Shell 裏輸入 db.users.help() 命令能夠看到下面的幫助信息:
> db.users.help() ... db.users.find([query],[fields]) - query is an optional query filter. fields is optional set of fields to return. e.g. db.users.find( {x:77} , {name:1, x:1} ) db.users.find(...).count() db.users.find(...).limit(n) db.users.find(...).skip(n) db.users.find(...).sort(...) ...
count、limit、skip、sort 等方法便是做用在 find 返回的遊標上。
下面咱們依據用戶的年齡按照 升序 或 降序 排列:
-- 1. 依據升序排列 > db.users.find({}, {name: 1, age: 1}).sort({age: 1}) -- 2. 依據降序排列 > db.users.find({}, {name: 1, age: 1}).sort({age: -1})
要實現分頁功能須要結合使用 skip(n) 和 limit(n) 兩個方法,它們的返回值也是一個遊標。skip 會選擇遊標的起始位置,limit 相似 SQL 的 limit 語句表示返回的結果集最大紀錄條數。
下面咱們查下年齡第二和第三大的用戶:
-- 1. 先看下年齡最大的 5 名用戶 > db.users.find({}, {name: true, age: 1}).sort({age: -1}).limit(5) -- 2. 再看下年齡第二和第三大的用戶 > db.users.find({}, {name: true, age: 1}).sort({age: -1}).skip(1).limit(2)
在 MongoDB 中能夠直接使用 db.YOUR_COLLECTION.count() 方法獲取集合記錄數,也能夠經過 db.YOUR_COLLECTION.find().count() 獲取:
獲取年齡大於等於 20 歲的用戶數:
> db.users.count({age: {$gte: 20}}) > db.users.find({age: {$gte: 20}}).count()
可是要知道 db.YOUR_COLLECTION.count() 僅僅是 db.YOUR_COLLECTION.find().count() 的別名,在它的內部仍是調用 db.YOUR_COLLECTION.find().count()
> db.users.count function (x) { return this.find(x).count(); }
更多有關做用於遊標的方法能夠查閱 遊標方法
TO BE CONTINUE