摘要:本文內容主要來自的學習,學習筆記基于個人理解對原書部分內容進行調整。如果需要練習相關命令行工具可直接閱讀本學習筆記。筆者測試數據庫版本較早,但文中涉及的所有概念及命令行工具基本適用于所有版本。二準備安裝和運行服務在學習之前,需要安裝環境。
感謝 Karl Seguin 編寫的 The Little MongoDB Book 這本 MongoDB 入門書。
本文內容主要來自「The Little MongoDB Book」的學習,學習筆記基于個人理解對原書部分內容進行調整。
如果你是 MongoDB 數據庫初學者,建議從學習「The Little MongoDB Book」 開始。
如果需要練習 MongoDB 相關命令行工具可直接閱讀本學習筆記。
筆者測試 MongoDB 數據庫版本較早,但文中涉及的所有 MongoDB 概念及命令行工具基本適用于所有版本。
一 簡介了解 MongoDB 前先了解 NoSQL,NoSQL 是一種數據存儲系統(非關系型數據庫系統),相比 MySQL 這類關系型數據庫提供通用的數據存儲解決方案,NoSQL 傾向負責解決系統中一部分數據存儲問題。
MongoDB 是一種 NoSQL 解決方案,提供更加通用的 NoSQL 方案。
本文約定 Mongo 和 MongoDB 都是代指 MongoDB 數據庫系統。
二 準備 2.1 安裝和運行 Mongo 服務在學習 MongoDB 之前,需要安裝 MongoDB 環境。可到 官方下載頁面 下載需要的 MongoDB 版本。
Windows 操作系統可以在 這里 下載對應的 MongoDB 安裝包。
解壓下載的包(到任意路徑)并進入 bin 子目錄,暫且不要執行任何命令。讓我先介紹一下,mongod 將啟動服務器進程,而 mongo 會打開客戶端的 shell,——大部分時間我們將和這兩個可執行文件打交道。
在 bin 子目錄中創建一個新的文本文件,取名為。
在 mongodb.config 中加一行:
dbpath=PATH_TO_WHERE_YOU_WANT_TO_STORE_YOUR_DATABASE_FILES
例如,在 Windows 中您需要添加的可能是 dbpath=c:mongodbdata,而在Linux下可能就是 dbpath=/etc/mongodb/data。
確認您指定的dbpath是存在的。
執行 mongod,帶上參數--config /path/to/your/mongodb.config。命令是這樣的 mongod --config /path/to/your/mongodb.config
上面的安裝步驟用于安裝和啟動 MongoDB 服務器進程。下面以 Windows 系統為例,講解 MongoDB 安裝及啟動詳細過程。
將安裝包解壓到 *c:mongodb*;
創建 c:mongodbdata 文件夾,該文件夾將用于存儲 MongoDB 的數據;
創建 c:mongodbinmongodb.config 配置文件并添加 dbpath=c:mongodbdata 配置;
命令行中進入 c:mongodbin 目錄,執行 c:mongodbinmongod --config c:mongodbinmongodb.config 啟動 Mongo 服務;
對于不創建 c:mongodbinmongodb.config配置的用戶,可以通過 --dbpath 參數啟動服務,執行 c:mongodbinmongod --dbpath c:mongodbdata;效果和使用 --config 參數一樣。
接下來,我們通過 SHELL 環境連接 MongoDB 服務。進入 c:mongodbin 目錄,執行 mongo 命令,即可完成 MongoDB 服務連接。
需要說明的是 MongoDB 在 c:mongodbin,提供了一些工具,其中就包括上去的 mongod.exe 和 mongo.exe,它們對應 mongod 和 mongo 命令。
2.2 MongoDB 基本概念如果有使用過關系型數據庫(如 MySQL),那么對數據庫、表、行、字段這些概念不會陌生,在 MongoDB 中也有類似的數據結構,不過在 Mongo 中將以另一種形式存在:
數據庫 (database)相當于 SQL 中的 database
集合 (collection)相當于 SQL 中的 table
文檔 (document)相當于 SQL 中的 row
域 (field)相當于 SQL 中的 column
索引 (index)相當于 SQL 中的 index
主鍵 (primaryKey)相當于 SQL 中的主鍵,但 MongoDB 會自動在插入(insert)數據時將 _id 域,設置為主鍵字段
MongoDB 和 關系型數據庫相關概念關系對照表:
SQL術語/概念 | MongoDB術語/概念 | 解釋/說明 |
---|---|---|
database | database | 數據庫 |
table | collection | 數據庫表/集合 |
row | document | 數據記錄行/文檔 |
column | field | 數據字段/域 |
index | index | 索引 |
table joins | 表連接,MongoDB不支持 | |
primary key | primary key | 主鍵,MongoDB自動將_id字段設置為主鍵 |
表格信息引用自 MongoDB 概念解析
2.2.1 與數據庫、集合、文檔相關常用命令下文中所有命令,需在命令終端執行。當使用 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 useset 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,) 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 的數據庫和數據集了,下面是一個小練習,來加深相關知識的使用及理解:
2.2.2 MongoDB 訓練場場景:我們開辟一個訓練場,將完成數據庫服務啟動、客戶端連接 MongoDB 服務、查看和選擇數據庫及數據庫刪除操作。
約定在 shell 中以 -- 開始的注釋說明信息:執行時請不要賦值注釋信息。
-- 1. 啟動一個 Windows 命令行窗口,開啟 MongoDB 服務 > cd c:mongodbin > mongod --config c:mongodbinmongodb.config -- 2. 另啟動一個 Windows 命令行窗口連接 MongoDB 服務 > cd c:mongodbin > 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)2.3 MongoDB 基本概念總結
MongoDB 有 數據庫 組成;數據庫由 集合 組成;集合由 文檔組成;文檔包含一個或多個 域;且集合可以被 索引,以提升 查找 和 排序 效率。
在關系型數據庫中在數據表(table)層級定義列(column)信息;在 NoSQL 中是在 文檔 這一層定義 域,即一個集合里的每個文檔都可以有自己的域。
MongoDB 中的集合是無模式的(schema-less),無需提前創建(即不需要像 SQL 一樣 CREATE TABLE 或 CREATE DATABASE)。
命令的分類
全局命令,使用 help 查看全局命令
當前數據庫級別命令,執行 db.help() 命令查看
當前集合級別命令,執行 db.your_collection.help() 命令查看。
另外需要說明的是 MongoDB 的 SHELL 運行于 JavaScript 之上。除全局命令外,操作 db 數據庫、 db.COLLECTION_NAME 操作集合,若缺少 () 將會在 SHELL 里打印出方法的實現源碼。
三 MongoDB CRUD 操作前面我們學習了如何使用 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 集合記錄。
3.1 CRUD - CREATE 創建 MongoDB 數據創建一個 文檔 由 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" ] }3.2 CRUD - RETRIEVE 查詢 MongoDB 數據
一個簡單的查詢操作可以使用 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"});3.2.1 條件查詢 3.2.1.1 基礎條件查詢 {fieldName: value}
查找用戶 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" }3.2.1.2 與 查詢 {fieldName1:value1, fieldName2:value2}
查找喜歡 跑步 的 男性
> 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 }3.2.1.3 或 查詢 {$or: [{fieldName: value1}, {fieldName: value2}]}
查找喜歡 乒乓球 或 瑜伽 的 男性
-- 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"}]})3.2.1.4 比較查詢
通過 $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.5 判斷文檔中是否存在某個域
在 3.2.1.4 的第 4 個示例 4. 查詢年齡不等于 18 歲的用戶 會查詢到沒有 age 域的用戶 Lee。通過 $exists 指令可以判斷某個域是否存在,它的值是 bool 類型,我們對這個示例做些改進:
-- 1. 查詢年齡字段存在且年齡不等于 18 歲的用戶 > db.users.find({age: {$ne: 18, $exists: true}})3.2 總結
本章了解了 MongoDB 相關查詢操作,了解更多查詢命令細節可以查看 查詢文檔。但更重要的是反復練習這些查詢語句的基本用法。
3.3 CRUD - UPDATE 更新 MongoDB 數據MongoDB 的更新需要特別關注一下,更新數據使用 db.YOUR_COLLECTIONS.update(query, object, options) 方法,update 接收兩個必選參數:查詢選擇器 和 需要更新的域。
3.3.1 UPDATE 覆蓋 與 UPDATE $set 更新一個簡單的示例,我們找到 年齡 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 }
建議: 在執行 刪除、更新 這類操作前,建議先采用相同的查詢條件查找數據,結果與判斷一致時再做 刪除、更新 等操作。
3.3.2 UPDATE $inc 和 $push 修飾符$inc 修飾符,對文檔中的某個域增加一個 正值 或 負值。
$push 修飾符,向域的值為數組中添加新值。
-- 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 }3.3.3 UPDATE upsert 選項: 插入新文檔或更新文檔域數據
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" }3.3.4 批量更新
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 方法相關具體使用。
3.4 CRUD - DELETE 刪除 MongoDB 數據通過 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.5 CRUD - 重識 RETRIEVE 查詢 MongoDB 數據我們在 3.2 章節中了解了有關 MongoDB 的查詢功能。本節我們將學習包括查詢指定域、排序、返回的結果集記錄數限制和分頁等功能,這些方法在應用程序開發過程中會十分常見。
3.5.1 返回指定域在 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} 顯示的排除掉。
3.5.2 排序在 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})3.5.3 分頁
要實現分頁功能需要結合使用 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)3.5.4 查詢集合記錄數
在 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
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/17732.html
摘要:在上安裝有兩種方法下載安裝包安裝使用安裝方式下載安裝包安裝注意在中不支持像方式,只好用方式來下載。再打開一個終端窗口,執行以下命令停止在開啟服務的控制臺,即可停止或者直接關閉開啟服務的控制臺。 在Mac上安裝MongoDB有兩種方法: 下載安裝包安裝 使用 brew 安裝 1. curl方式下載安裝包安裝 注意:在mac中不支持像wget方式,只好用curl方式來下載。 可以直接到...
摘要:在上安裝有兩種方法下載安裝包安裝使用安裝方式下載安裝包安裝注意在中不支持像方式,只好用方式來下載。再打開一個終端窗口,執行以下命令停止在開啟服務的控制臺,即可停止或者直接關閉開啟服務的控制臺。 在Mac上安裝MongoDB有兩種方法: 下載安裝包安裝 使用 brew 安裝 1. curl方式下載安裝包安裝 注意:在mac中不支持像wget方式,只好用curl方式來下載。 可以直接到...
背景 學習MongoDB,并做筆記整理,以便于用到時查看。 MogoDB NoSQL Database(JS) 使用方便,想存就存,相取就取 是MEAN中的M(數據) 安裝 https://www.mongodb.com/downl... 選擇相應系統安裝包 安裝mongoose 創建一個文件夾,并npm init --yes,創建package.js npm install mongoos...
摘要:學習筆記一安裝測試配置下載安裝從官網下載對應的壓縮包解壓即可。 mongo學習筆記 一 安裝測試配置 1 下載安裝 從mongodb官網下載對應的壓縮包,解壓即可。 copy命令到/usr/local/bin目錄 (cp mongod /usr/local/bin;cp mongo /usr/local/bin) 2 創建配置文件 參考官方文檔https:/...
閱讀 1329·2021-11-15 11:37
閱讀 2213·2021-09-23 11:21
閱讀 1299·2019-08-30 15:55
閱讀 2105·2019-08-30 15:55
閱讀 2815·2019-08-30 15:52
閱讀 2818·2019-08-30 11:12
閱讀 1572·2019-08-29 18:45
閱讀 1885·2019-08-29 14:04