摘要:簡述與同為數據庫但是為數據庫而為文檔型數據庫存儲的是文檔的二進制化內部執行引擎為解釋器把文檔存儲成結構在查詢時轉換為對象并可以通過熟悉的語法來操作的安裝啟動在上直接下載解壓運行即可本身是已編譯好的二進制可執行文件如果報錯說明你的服務器和
簡述
mongoDB與redis同為noSql數據庫,但是redis為kv數據庫(key/value),而mongoDB為文檔型數據庫存儲的是文檔(Bson->json的二進制化).內部執行引擎為JS解釋器, 把文檔存儲成bson結構,在查詢時,轉換為JS對象,并可以通過熟悉的js語法來操作
mongoDB的安裝啟動在linux上直接下載解壓運行即可,本身是已編譯好的二進制可執行文件.
如果報錯
-bash: /usr/local/mongodb/bin/mongod: cannot execute binary file
說明你的服務器和mongodb 的版本不對應, 如果服務器是64位,下載x86_64的mongodb ,如果服務器是32位的, 下載i686的mongodb/
bsondump 導出BSON結構 mongo 客戶端 mongod 服務端 mongodump 整體數據庫二進制導出 mongoexport 導出易識別的json文檔或csv文檔 mongorestore 數據庫整體導入 mongos 路由器(分片用) mongofiles GridFS工具,內建的分布式文件系統 mongoimport 數據導入程序 mongotop 運維監控 mongooplog mongoperf mongostat啟動
#啟動服務端 ./mongod --dbpath /usr/local/mongodb/data --logpath /usr/local/mongodb/logs/mongo.log --fork --port 27017 #啟動客戶端 ./mongo ./mongo --host xxx -u adminUserName -p userPassword --authenticationDatabase admin #可遠程登錄并指定登錄用戶以及數據庫目錄
注意:
關于日志文件和數據存儲路徑的指定一定要是正確的,否則就會報如下錯誤
ERROR: child process failed, exited with error number 1
mongodb非常的占磁盤空間, 剛啟動后要占3-4G左右,如果你用虛擬機練習,可能空間不夠,導致無法啟動.可以用 --smallfiles 選項來啟動, 將會占用較小空間,大約400M左右.
32位的mongo客戶端貌似會出現段錯誤(segmentation fault)
mongodb服務器啟動時, 默認不是需要認證的.
要讓用戶生效, 需要啟動服務器時,就指定--auth選項.這樣, 操作時,就需要認證了(另外也可以在其配置文件中指定)
參數解釋:
--dbpath 數據存儲目錄 --logpath 日志存儲目錄 --port 運行端口(默認27017) --fork 后臺進程運行mongodb 命令行 系統與庫表級命令 查看當前的數據庫
show dbs/databases
注意: databases 這個命令只存在在新版本中。
選庫/創建庫Mongodb的庫是隱式創建,你可以use 一個不存在的庫
然后在該庫下創建collection,即可創建庫
use databaseName創建collection
db.createCollection("collectionName")
collection同樣允許隱式創建:
db.collectionName.insert(json);查看當前庫下的collection
show tables/collections刪除collection
db.collectionName.drop()刪除database
db.dropDatabase() # 選擇之后使用顯示用戶
show usershelp命令
db.help() db.youColl.find().help();DML命令 insert/save
介紹: mongodb存儲的是文檔,文檔是json格式的對象.
語法: db.collectionName.isnert(document);
# 增加單篇文檔,默認有一個ID db.collectionName.insert({title:"nice day"}); # 增加單個文檔,并指定_id db.collectionName.insert({_id:8,age:78,name:"lisi"}); # 增加多個文檔 db.collectionName.insert( [ {time:"friday",study:"mongodb"}, {_id:9,gender:"male",name:"QQ"} ] ) # insert 與 save的區別 : 如果插入的數據的_id相同,save將會更新該文檔,而insert將會報錯 > db.user.find(); { "_id" : 6, "sex" : "nan" } { "_id" : 1, "name" : "zxg" } { "_id" : 2, "name" : "user2", "age" : 2 } { "_id" : 3, "name" : "user3", "age" : 3 } > db.user.insert({_id:3,name:"zhouzhou"}); WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error index: user.user.$_id_ dup key: { : 3.0 }" } }) > db.user.save({_id:3,name:"zhouzhou"}); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.find(); { "_id" : 6, "sex" : "nan" } { "_id" : 1, "name" : "zxg" } { "_id" : 2, "name" : "user2", "age" : 2 } { "_id" : 3, "name" : "zhouzhou" }remove
語法: db.collection.remove(查詢表達式, 選項);
選項是指 {justOne:true/false},是否只刪一行, 默認為false
注意
查詢表達式依然是個json對象
查詢表達式匹配的行,將被刪掉.
如果不寫查詢表達式,collections中的所有文檔將被刪掉. 在最新版本的mongodb,必須要寫表達式才可以刪除
> db.user.find() { "_id" : 1, "name" : "user1","age" : 1 } { "_id" : 2, "name" : "user2","age" : 2 } { "_id" : 3, "name" : "user3","age" : 3 } { "_id" : 4, "name" : "user4","age" : 4 } { "_id" : 5, "name" : "user5","age" : 5 } { "_id" : 6, "sex" : "nan" } > db.user.remove({name:/user*/i},1) # 可以通過正則刪除,并且只刪除第1行 > db.user.find() { "_id" : 2, "name" : "user2","age" : 2 } { "_id" : 3, "name" : "user3","age" : 3 } { "_id" : 4, "name" : "user4","age" : 4 } { "_id" : 5, "name" : "user5","age" : 5 } { "_id" : 6, "sex" : "nan" } > db.user.remove({name:/user*/i}); # 刪除所有user開頭的 > db.user.remove({age:{$gte:4}}); # 刪除年齡大于或等于4的,這里的查詢表達式參考下文的find部分,會有詳細的說明update
語法: db.collection.update(criteria,objNew,upsert,multi)
criteria: 設置查詢條件,用于查詢哪些文檔需要被更新.這里可以組合非常復雜的查詢條件
objNew: 更新后的對象
upsert: 設置為真的時候如果記錄已經存在,更新它,否則新增一個記錄 默認為false
multi: 設置為真的時候,將會更新所有符合查詢條件的文檔.在mongodb中默認情況下只會更新第一條符合的文檔.
1.錯誤的更改
> db.user.find(); { "_id" : 6, "sex" : "nan" } { "_id" : 1, "name" : "user1", "age" : 1 } { "_id" : 2, "name" : "user2", "age" : 2 } { "_id" : 3, "name" : "user3", "age" : 3 } > db.user.update({name:"user1"},{name:"zxg"}); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.find(); { "_id" : 6, "sex" : "nan" } { "_id" : 1, "name" : "zxg" } { "_id" : 2, "name" : "user2", "age" : 2 } { "_id" : 3, "name" : "user3", "age" : 3 } > db.user.update({name:"xb"},{name:"jyh"},1); # 沒有就添加 WriteResult({ "nMatched" : 0, "nUpserted" : 1, # upserted 表示更新失敗后插入; "nModified" : 0, "_id" : ObjectId("55bf37d6ea4ed1b30ffb368d") }) { "_id" : ObjectId("55bf3480ea4ed1b30ffb368c"), "name" : "jyh" } > db.user.update({name:"jyh"},{name:"zxg"},1,1); #全部更改,但是報錯,多條更新必須要有表達式 "writeError" : { "code" : 9, "errmsg" : "multi update only works with $ operators" }
結果: 文檔中的其他列也不見了,改后只有_id和name列了.
即--新文檔直接替換了舊文檔,而不是修改
2.通過修改表達式正確修改
$set # 當文檔中包含該字段的時候,更新該字段,如果該文檔中沒有該字段,則為本文檔添加一個字段. $unset # 刪除文檔中的一個字段. $rename # 重命名某個列 $inc # 增長某個列 $setOnInsert # 當upsert為true時,并且發生了insert操作時,可以補充的字段 $push # 將一個數字存入一個數組,分為三種情況,如果該字段存在,則直接將數字存入數組.如果該字段不存在,創建字段并且將數字插入該數組.如果更新的字段不是數組,會報錯的. $pushAll # 將多個數值一次存入數組.上面的push只能一個一個的存入 $addToSet # 與$push功能相同將一個數字存入數組,不同的是如果數組中有這個數字,將不會插入,只會插入新的數據,同樣也會有三種情況,與$push相同. $pop #刪除數組最后一個元素 $pull # 刪除數組中的指定的元素,如果刪除的字段不是數組,會報錯 $pullAll # 刪除數組中的多個值,跟pushAll與push的關系類似.
update有以上條件操作符以后才能使用第4參數進行多文檔更新操作;
# set 僅更改文檔中某列的值 db.user.update({name:"user1"},{$set:{name:"zxg"}},0,1); # 把所有name為user1的更改為zxg,僅更改此列 # unset 刪除文檔某一列 db.user.update({name:"zxg"},{$unset:{age:1}}) # 把name為zxg的列的列名name更改為xm db.user.update({name:"zxg"},{$rename: {name:"xm"}}) # 減少年齡1歲 db.user.update({name:"user2"},{$inc:{age:-1}}); # 增長年齡1歲 db.user.update({name:"user2"},{$inc:{age:1}}); # 更新_id為7的文檔,如果該文檔不存在就創建并增加work字段,并指定值(可多個值指定),update第三參數upsert必須為true; db.user.update({_id:7},{$setOnInsert:{work:"go on"}},1) WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 7 })
# $push db.test.find() { "_id" : 1, "ary" : [ 1, 2, 3, 4 ] } { "_id" : 2, "text" : "test" } db.test.update({_id:1},{$push:{ary:5}}) # 數組存在 直接壓入,但是這個地方如果是數組的話就壓入一個數組,并非是合并數組中的元素 db.test.update({_id:1},{$push:{ary:[8,9,10]}}) db.test.find() { "_id" : 2, "text" : "test" } { "_id" : 1, "ary" : [ 1, 2, 3, 4, 5,[8,9,10] ] } # 由此可見push一次只能插入一個字段,如果想要批量插入的話就緩存pushAll; db.test.update({_id:2},{$push:{ary:6}}) # 數組不存在,創建數組并存入 db.test.find() { "_id" : 2, "ary" : [ 6 ], "text" : "test" } { "_id" : 1, "ary" : [ 1, 2, 3, 4, 5 ] } db.test.update({_id:2},{$push:{text:6}}) # 更新字段存在但不是數組報錯 Cannot apply $push/$pushAll modifier to non-array # pop db.user.update({_id:9},{$pop:{test:0}}) # 這里的test無論傳入什么值,都是刪掉test數組的最后一個 # $pull db.user.update({_id:9},{$pull:{test:2}}) #這里的test傳什么值就刪掉什么值自增唯一性ID方案findandmodify
在查詢的同時進行更改
db.collection.findAndModify({ query:, // 查詢過濾條件 sort: , //如果多個文檔符合查詢過濾條件,將以該參數指定的排列方式選擇出排在首位的對象 remove: , // Must specify either the remove or the update field. Removes the document specified in the query field. Set this to true to remove the selected document . The default is false. update: , // Must specify either the remove or the update field. Performs an update of the selected document. The update field employs the same update operators or field: value specifications to modify the selected document. new: , // Optional. When true, returns the modified document rather than the original. The findAndModify() method ignores the new option for remove operations. The default is false. fields: , //Optional. A subset of fields to return. The fields document specifies an inclusion of a field with 1, as in: fields: { : 1, : 1, ... } upsert: //Optional. Used in conjunction with the update field. When true, findAndModify() creates a new document if no document matches the query, or if documents match the query, findAndModify() performs an update. To avoid multiple upserts, ensure that the query fields are uniquely indexed.The default is false. });
db.people.findAndModify({ query: { name: "Tom", state: "active", rating: { $gt: 10 } }, sort: { rating: 1 }, update: { $inc: { score: 1 } } }) db.runCommand({ findandmodify : "users", query: {age: {$gte: 25}}, sort: {age: -1}, update: {$set: {name: "a2"}, $inc: {age: 2}}, remove: true });自增ID處理
> db.unique.insert({id:0}); WriteResult({ "nInserted" : 1 }) > db.unique.findAndModify({update:{$inc:{id:1}} }) {"id" : 0 } > db.unique.findAndModify({update:{$inc:{id:1}} }) {"id" : 1 } //獲得ID以后就插入到需要有自增ID的collection中深入查詢表達式 查找某集合所有文檔
db.collection.find()等值查詢
db.collection.find({filed:value})返回文檔的某些值
db.user.find({name:"user0"},{age:1}) { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "age" : 0 } { "_id" : ObjectId("5198c3cac686eb50e2c843bd"), "age" : 20 } #_id是默認顯示的,可以傳入_id:0來隱藏它不等于 $ne
db.collection.find({filed:{$ne:value}})not in $nin
db.collection.find({filed:{$nin:[value1,value2,value3]}})數組查詢$all $in
$all 數組中必須包含所有給定的查詢的元素
$in 數組中只要包含給定的查詢元素就可以
> db.phone.find() { "_id" : ObjectId("5198e20220c9b0dc40419385"), "num" : [ 1, 2, 3 ] } { "_id" : ObjectId("5198e21820c9b0dc40419386"), "num" : [ 4, 2, 3 ] } { "_id" : ObjectId("5198e22120c9b0dc40419387"), "num" : [ 1, 2, 5 ] } > db.phone.find({num:{$all:[1,2]}}) { "_id" : ObjectId("5198e20220c9b0dc40419385"), "num" : [ 1, 2, 3 ] } { "_id" : ObjectId("5198e22120c9b0dc40419387"), "num" : [ 1, 2, 5 ] } > db.phone.find({num:{$all:[1,4]}}) # 同時包含1,4的沒有數據 > db.phone.find({num:{$in:[1,4]}}) # 包含1或4的數據 { "_id" : ObjectId("5198e20220c9b0dc40419385"), "num" : [ 1, 2, 3 ] } { "_id" : ObjectId("5198e21820c9b0dc40419386"), "num" : [ 4, 2, 3 ] } { "_id" : ObjectId("5198e22120c9b0dc40419387"), "num" : [ 1, 2, 5 ] }查找包含該字段的文檔 $exists
> db.phone.find() { "_id" : ObjectId("5198e20220c9b0dc40419385"), "num" : [ 1, 2, 3 ] } { "_id" : ObjectId("5198e21820c9b0dc40419386"), "num" : [ 4, 2, 3 ] } { "_id" : ObjectId("5198e22120c9b0dc40419387"), "num" : [ 1, 2, 5 ] } { "_id" : ObjectId("5198e51a20c9b0dc40419388"), "state" : 1 } > db.phone.find({state:{$exists:1}}) # 存在state字段的 { "_id" : ObjectId("5198e51a20c9b0dc40419388"), "state" : 1 } > db.phone.find({state:{$exists:0}}) # 不存在state字段的文檔 { "_id" : ObjectId("5198e20220c9b0dc40419385"), "num" : [ 1, 2, 3 ] } { "_id" : ObjectId("5198e21820c9b0dc40419386"), "num" : [ 4, 2, 3 ] } { "_id" : ObjectId("5198e22120c9b0dc40419387"), "num" : [ 1, 2, 5 ] }取模操作 $mod
> db.user.find() { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 3 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 5 } { "_id" : ObjectId("5198c286c686eb50e2c843b8"), "name" : "user6", "age" : 6 } { "_id" : ObjectId("5198c286c686eb50e2c843b9"), "name" : "user7", "age" : 7 } { "_id" : ObjectId("5198c286c686eb50e2c843ba"), "name" : "user8", "age" : 8 } { "_id" : ObjectId("5198c286c686eb50e2c843bb"), "name" : "user9", "age" : 9 } { "_id" : ObjectId("5198c286c686eb50e2c843bc"), "name" : "user10", "age" : 10 } { "_id" : ObjectId("5198c3cac686eb50e2c843bd"), "name" : "user0", "age" : 20 } > db.user.find({age:{$mod:[3,1]}}) # 模三余一 { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } { "_id" : ObjectId("5198c286c686eb50e2c843b9"), "name" : "user7", "age" : 7 } { "_id" : ObjectId("5198c286c686eb50e2c843bc"), "name" : "user10", "age" : 10 }
同樣使用 db.user.find("this.age%3==1")這個語句也能達到上面的效果,但是不推薦.
滿足一個 $or> db.user.find() { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 3 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 5 } { "_id" : ObjectId("5198c286c686eb50e2c843b8"), "name" : "user6", "age" : 6 } { "_id" : ObjectId("5198c286c686eb50e2c843b9"), "name" : "user7", "age" : 7 } { "_id" : ObjectId("5198c286c686eb50e2c843ba"), "name" : "user8", "age" : 8 } { "_id" : ObjectId("5198c286c686eb50e2c843bb"), "name" : "user9", "age" : 9 } { "_id" : ObjectId("5198c286c686eb50e2c843bc"), "name" : "user10", "age" : 10 } { "_id" : ObjectId("5198c3cac686eb50e2c843bd"), "name" : "user0", "age" : 20 } > db.user.find({$or:[{name:"user1"},{age:20}]}) # 由此可見or的鍵值為一個數組 { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c3cac686eb50e2c843bd"), "name" : "user0", "age" : 20 }都不滿足(排除) $nor
> db.user.find({$nor:[{name:"user1"},{age:20}]}) # name不等于user1,以及age不等于20,可以理解為排除; { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 3 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 5 } { "_id" : ObjectId("5198c286c686eb50e2c843b8"), "name" : "user6", "age" : 6 } { "_id" : ObjectId("5198c286c686eb50e2c843b9"), "name" : "user7", "age" : 7 } { "_id" : ObjectId("5198c286c686eb50e2c843ba"), "name" : "user8", "age" : 8 } { "_id" : ObjectId("5198c286c686eb50e2c843bb"), "name" : "user9", "age" : 9 } { "_id" : ObjectId("5198c286c686eb50e2c843bc"), "name" : "user10", "age" : 10 }查詢數組的長度等于給定數組長度的文檔 $size
> db.phone.find() { "_id" : ObjectId("5198e20220c9b0dc40419385"), "num" : [ 1, 2, 3 ] } { "_id" : ObjectId("5198e21820c9b0dc40419386"), "num" : [ 4, 2, 3 ] } { "_id" : ObjectId("5198e22120c9b0dc40419387"), "num" : [ 1, 2, 5 ] } { "_id" : ObjectId("5198e51a20c9b0dc40419388"), "state" : 1 } { "_id" : ObjectId("519969952b76790566165de2"), "num" : [ 2, 3 ] } > db.phone.find({num:{$size:4}}) # num數組長度為4的結果沒有 > db.phone.find({num:{$size:3}}) # 長度為3的有三個 { "_id" : ObjectId("5198e20220c9b0dc40419385"), "num" : [ 1, 2, 3 ] } { "_id" : ObjectId("5198e21820c9b0dc40419386"), "num" : [ 4, 2, 3 ] } { "_id" : ObjectId("5198e22120c9b0dc40419387"), "num" : [ 1, 2, 5 ] }自定義的查詢 $where
由bson轉換為json,然后再通過回調函數去判斷,性能很差,能不用盡量別用
> db.user.find() { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 3 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 5 } { "_id" : ObjectId("5198c286c686eb50e2c843b8"), "name" : "user6", "age" : 6 } { "_id" : ObjectId("5198c286c686eb50e2c843b9"), "name" : "user7", "age" : 7 } { "_id" : ObjectId("5198c286c686eb50e2c843ba"), "name" : "user8", "age" : 8 } { "_id" : ObjectId("5198c286c686eb50e2c843bb"), "name" : "user9", "age" : 9 } { "_id" : ObjectId("5198c286c686eb50e2c843bc"), "name" : "user10", "age" : 10 } { "_id" : ObjectId("5198c3cac686eb50e2c843bd"), "name" : "user0", "age" : 20 } > db.user.find({$where:function(){return this.age == 3 || this.age == 4}}) # 回調,進入了隱式迭代,然后符合條件的才返回; { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 3 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } # 如今的新版本也可以直接寫where條件 db.goods.find({$where:"this.cat_id != 3 && this.cat_id != 11"});根據數據類型查詢 $type
在mongodb中每一種數據類型都有對應的數字,我們在使用$type的時候需要使用這些數字,文檔中給出如下的表示
|類型|編號|
|:-:|:-:|
|雙精度|1|
|字符串|2|
|對象|3|
|數組|4|
|二進制數據|5|
|對象 ID|7|
|布爾值|8|
|日期|9|
|空|10|
|正則表達式|11|
|JavaScript|13|
|符號|14|
|JavaScript(帶范圍)|15|
|32 位整數|16|
|時間戳|17|
|64 位整數|18|
|最小鍵|255|
|最大鍵|127|
> db.user.find() { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 3 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 5 } { "_id" : ObjectId("5198c286c686eb50e2c843b8"), "name" : "user6", "age" : 6 } { "_id" : ObjectId("5198c286c686eb50e2c843b9"), "name" : "user7", "age" : 7 } { "_id" : ObjectId("5198c286c686eb50e2c843ba"), "name" : "user8", "age" : 8 } { "_id" : ObjectId("5198c286c686eb50e2c843bb"), "name" : "user9", "age" : 9 } { "_id" : ObjectId("5198c286c686eb50e2c843bc"), "name" : "user10", "age" : 10 } { "_id" : ObjectId("5198c3cac686eb50e2c843bd"), "name" : "user0", "age" : 20 } { "_id" : ObjectId("51996ef22b76790566165e47"), "name" : 23, "age" : 33 } > db.user.find({name:{$type:1}}) # 查找name為雙精度的文檔 { "_id" : ObjectId("51996ef22b76790566165e47"), "name" : 23, "age" : 33 }正則表達式
正則的效率都知道的,得一一解析后再查找,所以效率也是很低;
> db.user.find({name:/user.*/i}) # 查詢name以user開頭不區分大小寫的文檔 > db.goods.find({goods_name:/諾基亞.*/},{goods_name:1}); # 以諾基亞開頭的商品范圍查詢
小于 $lt
大于 $gt
小于或等于 $lte
大于或等于 $gte
limit> db.user.find({age:{$gte:5}}).limit(3) # 限制返回的是三條數據 { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 5 } { "_id" : ObjectId("5198c286c686eb50e2c843b8"), "name" : "user6", "age" : 6 } { "_id" : ObjectId("5198c286c686eb50e2c843b9"), "name" : "user7", "age" : 7 }分頁查詢
使用到skip 和limit方法.skip表示跳過前面的幾個文檔,limit表示顯示幾個文檔.
> db.user.find() { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 2 } > db.user.find().skip(2).limit(3) # 跳過前兩個文檔查詢后面的三個文檔,經過測試這兩個方法的使用順序沒有影響 { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 1 } > db.user.find().limit(3).skip(2) { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 1 }sort 排序
在mongodb中排序很簡單,使用sort方法,傳遞給它你想按照哪個字段的哪種方式排序即可.這里1代表升序,-1代表降序.
> db.user.find() { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 3 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 5 } > db.user.find().sort({age:1}) { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 3 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 5 } > db.user.find().sort({age:-1}) { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 5 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 4 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 3 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 }group 分組查詢
mongodb中的group可以實現類似關系型數據庫中的分組的功能,但是mongodb中的group遠比關系型數據庫中的group強大,可以實現map-reduce功能,關于什么是map-reduce,會在后續大數據專題里面說明,這里先略過,感興趣的朋友可以百度
group中的json參數類似這樣{key:{字段:1},initial:{變量:初始值},$reduce:function(doc,prev){函數代碼}}.
其中的字段代表,需要按哪個字段分組.
變量表示這一個分組中會使用的變量,并且給一個初始值.可以在后面的$reduce函數中使用.
$reduce的兩個參數,分別代表當前的文檔和上個文檔執行完函數后的結果.如下我們按年齡分組,同級不同年齡的用戶的多少:
> db.user.find() { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 2 } > db.user.group({key:{age:1},initial:{count:0},$reduce:function(doc,prev){prev.count++}}) [ { "age" : 0, "count" : 1 }, { "age" : 1, "count" : 3 }, { "age" : 2, "count" : 2 } ] > db.user.group({key:{age:1},initial:{users:[]},$reduce:function(doc,prev){prev.users.push(doc.name)}}); #由于內部是使用js引擎來解析的,所以完全可以通過js語法來操作,這使得雖然mongodb的分組很麻煩但卻很靈活 [ { "age" : 0, "users" : [ "user0" ] }, { "age" : 1, "users" : [ "user1", "user3", "user4" ] }, { "age" : 2, "users" : [ "user2", "user5" ] } ] # 另外本函數還有兩個可選參數 condition 和 finalize # condition就是分組的條件篩選類似mysql中的having > db.user.group({key:{age:1},initial:{users:[]},$reduce:function(doc,prev){prev.users.push(doc.name)},condition:{age:{$gt:0}}}) # 篩選出age大于0的; [ { "age" : 1, "users" : [ "user1", "user3", "user4" ] }, { "age" : 2, "users" : [ "user2", "user5" ] } ]count 統計
> db.goods.count() #不傳參數就統計該集合的總數 31 > db.goods.count({cat_id:3}) # 統計cat_id=3的總數 15distinct 排重
> db.user.find() { "_id" : ObjectId("5198c286c686eb50e2c843b2"), "name" : "user0", "age" : 0 } { "_id" : ObjectId("5198c286c686eb50e2c843b3"), "name" : "user1", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b4"), "name" : "user2", "age" : 2 } { "_id" : ObjectId("5198c286c686eb50e2c843b5"), "name" : "user3", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b6"), "name" : "user4", "age" : 1 } { "_id" : ObjectId("5198c286c686eb50e2c843b7"), "name" : "user5", "age" : 2 } > db.user.distinct("age") # 略微有點特殊,傳入的參數直接是字符串,而不是對象; [ 0, 1, 2 ]子文檔查詢 $elemMatch與對象中的屬性
{ _id: 1, results: [ 82, 85, 88 ] } { _id: 2, results: [ 75, 88, 89 ] } db.scores.find( { results: { $elemMatch: { $gte: 80, $lt: 85 } } } #查詢results文檔中的元素同時滿足即大于80并且又小于85的,注意此處只要其中一個元素滿足這個查詢就會返回 ) { "_id" : 1, "results" : [ 82, 85, 88 ] }
> db.user.find(); { "_id" : ObjectId("55c070a02cc8cec37073a1d9"), "name" : "zxg", "age" : 28, "hobby" : { "life" : [ "電影", "小說", "漫畫" ], "work" : [ "發呆", "發呆2" ], "home" : "玩耍" } } { "_id" : ObjectId("55c070a52cc8cec37073a1da"), "name" : "jyh", "age" : 28, "hobby" : { "life" : [ "賣萌", "養兔子", "做家務" ], "work" : [ "郁悶", "郁悶2" ], "home" : "賣萌" } } { "_id" : ObjectId("55c072db2cc8cec37073a1db"), "name" : "jyh", "age" : 28, "hobby" : [ { "life" : [ "賣萌", "養兔子", "做家務" ] }, { "work" : [ "郁悶", "郁悶2" ] }, { "home" : "賣萌" } ] } > db.user.find({hobby:{$elemMatch:{home:"賣萌"}}}) # 注意上文的結構,必須是要在數組中才可以查出 { "_id" : ObjectId("55c072db2cc8cec37073a1db"), "name" : "jyh", "age" : 28, "hobby" : [ { "life" : [ "賣萌", "養兔子", "做家務" ] }, { "work" : [ "郁悶", "郁悶2" ] }, { "home" : "賣萌" } ] } > db.user.find({"hobby.home":"賣萌"}) # 注意,hobby.home類似js中對象與屬性的操作方式,但是要加上引號,否則會報錯 { "_id" : ObjectId("55c070a52cc8cec37073a1da"), "name" : "jyh", "age" : 28, "hobby" : { "life" : [ "賣萌", "養兔子", "做家務" ], "work" : [ "郁悶", "郁悶2" ], "home" : "賣萌" } } { "_id" : ObjectId("55c072db2cc8cec37073a1db"), "name" : "jyh", "age" : 28, "hobby" : [ { "life" : [ "賣萌", "養兔子", "做家務" ] }, { "work" : [ "郁悶", "郁悶2" ] }, { "home" : "賣萌" } ] }查詢實例
以下查詢基于ecshop網站的數據查詢
# 本店價格低于或等于100元的商品($lte) db.goods.find({shop_price:{$lte:100}},{goods_name:1,shop_price:1}); # 取出第4欄目或第11欄目的商品($in) db.goods.find({cat_id:{$in:[4,11]}},{goods_name:1,shop_price:1}); # 取出100<=價格<=500的商品($and) db.goods.find({$and:[{"shop_price":{$gte:100}},{"shop_price":{$lte:500}}]},{_id:0,shop_price:1}) # 取出不屬于第3欄目且不屬于第11欄目的商品($and $nin和$nor分別實現) db.goods.find({$and:[{cat_id:{$ne:3}},{cat_id:{$ne:11}}]},{_id:0,cat_id:1}) db.goods.find({cat_id:{$nin:[3,11]}},{_id:0,cat_id:1}) db.goods.find({$nor:[{cat_id:3},{cat_id:11}]},{_id:0,cat_id:1}) # 取出價格大于100且小于300,或者大于2000且小于5000的商品() db.goods.find({$or:[{$and:[{shop_price:{$gt:100}}, {shop_price:{$lt:300} }]}, {$and:[{shop_price:{$gt:2000}}, {shop_price:{$lt:5000} }] } ] },{_id:0,shop_price:1} ) # 取出所有goods_id為偶數的商品; db.goods.find({goods_id:{$mod:[2,0]}},{_id:0,goods_id:1})
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/18811.html
摘要:步優化以及其它數據庫后端掘金原文鏈接在發表了一篇簡潔有效有趣和令人信服的分鐘教程描述了如何進行優化。關于的七種后端掘金對于的,在學習起來可能是比較亂的。 5 步優化 MongoDB 以及其它數據庫 - 后端 - 掘金原文鏈接 Jared Rosoff 在 Scale Out Camp 發表了一篇簡潔、有效、有趣和令人信服的《8 分鐘 MongoDB 教程》描述了如何進行 MongoDB...
摘要:基礎篇整合最近有朋友也想學習相關方面的知識,如果你是后端想接近前端,作為一門跑在服務端的語言從這里入門再好不過了。事件驅動機制是通過內部單線程高效率地維護事件循環隊列來實現的,沒有多線程的資源占用和上下文的切換。 nodeJs 基礎篇整合 最近有朋友也想學習nodeJs相關方面的知識,如果你是后端想接近前端,node作為一門跑在服務端的JS語言從這里入門再好不過了。如果你正好喜歡前端,...
摘要:基礎篇整合最近有朋友也想學習相關方面的知識,如果你是后端想接近前端,作為一門跑在服務端的語言從這里入門再好不過了。事件驅動機制是通過內部單線程高效率地維護事件循環隊列來實現的,沒有多線程的資源占用和上下文的切換。 nodeJs 基礎篇整合 最近有朋友也想學習nodeJs相關方面的知識,如果你是后端想接近前端,node作為一門跑在服務端的JS語言從這里入門再好不過了。如果你正好喜歡前端,...
閱讀 2856·2021-10-14 09:42
閱讀 3174·2019-08-30 15:52
閱讀 3240·2019-08-30 14:02
閱讀 1102·2019-08-29 15:42
閱讀 529·2019-08-29 13:20
閱讀 1157·2019-08-29 12:24
閱讀 470·2019-08-26 10:20
閱讀 680·2019-08-23 18:31