mongoDB 數據庫
mongoDB 數據庫概念
MongoDB的一個實例可以擁有一個或多個相互獨立的數據庫,每個數據庫都有自己的集合。
集合
集合可以看作是擁有動態模式的表。
文檔
文檔是MongoDB中基本的數據單元,類似關係型數據庫表的行。
文檔是鍵值對的一個有序集合。
_id
每個文檔都有個特殊的"_id",在文檔所屬集合中是唯一的。
mongo命令 鏈接MongoDB 數據庫時 會進入 javascript shell
MongoDB自帶了一個功能強大的JavaScript Shell,可以用於管理或操作MongoDB。
數據庫命名規則
* 1:不能是空串。
* 2:不得含有/、\、?、$、空格、空字符等等,基本只能使用ASCII中的字母和數字 。
* 3:區分大小寫,建議全部小寫。
* 4:最多爲64字節。
* 5:不得使用保留的數據庫名,比如:admin,local,config
注意:數據庫最終會成爲文件,數據庫名就是文件的名稱。
集合名稱定義規則
1: 不能是空串。
2: 不能包含\0字符(空字符),這個字符表示集合名的結束,也不能包含”$”。
3: 不能以”system.”開頭,這是爲系統集合保留的前綴
文檔的key定義規則
* 1: 不能包含\0字符(空字符),這個字符表示鍵的結束。
* 2: “.”和“$”是被保留的,只能在特定環境下用。
* 3: 區分類型,同時也區分大小寫。
* 4: 鍵不能重複
注意:文檔的鍵值對是有順序的,相同的鍵值對如果有不同順序的話,也是不同的文檔。
數據庫操作
顯示現有的數據庫。
show dbs
leyue 0.078GB
local 0.078GB
mongo 0.078GB
mycol 0.078GB
mydb 0.078GB
testdb 0.078GB
顯示當前使用的數據。
db
切換當前使用的數據庫。
use leyue
創建數據庫
use 數據庫名稱
db.集合名稱.insert({"name":"wang wu"})
創建數據庫:MongoDB沒有專門創建數據庫的語句,可以使用“use” 來使用某個數據庫,如果要使用
的數據庫不存在,那麼將會創建一個,會在真正向該庫加入文檔後,保存成爲文件。
刪除數據庫
use 數據庫名稱
db.dropDatabase()
集合的操作
創建集合
創建集合:在MongoDB中不用創建集合,因爲沒有固定的結構,直接使用db.集合名稱.命令 來操作就可
以了。如果非要顯示創建集合的話,用:db.createCollecion(“集合名稱”);
顯示現有的集合
use leyue
show collections
insert 可以插入一個用{} 多條數據用[]
db.userdatas.insert([ {"name":'lisan',"age":23},{"name":"wang wu","age":33} ])
1:MongoDB會爲每個沒有“_id”字段的文檔自動添加一個”_id”字段
2:每個Doc必須小於16MB
刪除文檔 db.集合.remove()
db.userdatas.remove({"name":"lisan"})
查看數據庫 文檔狀態 可以看到文檔的個數大小 等等信息
數據庫: db.stats()
文檔:db.集合.stats
db.stats()
{
"db" : "leyue",
"collections" : 4,
"objects" : 418,
"avgObjSize" : 110.77511961722487,
"dataSize" : 46304,
"storageSize" : 192512,
"numExtents" : 6,
"indexes" : 2,
"indexSize" : 32704,
"fileSize" : 67108864,
"nsSizeMB" : 16,
"extentFreeList" : {
"num" : 0,
"totalSize" : 0
},
"dataFileVersion" : {
"major" : 4,
"minor" : 22
},
"ok" : 1
}
db.userdatas.stats()
{
"ns" : "leyue.userdatas",
"count" : 11,
"size" : 1040,
"avgObjSize" : 94,
"numExtents" : 1,
"storageSize" : 8192,
"lastExtentSize" : 8192,
"paddingFactor" : 1,
"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.",
"userFlags" : 1,
"capped" : false,
"nindexes" : 1,
"totalIndexSize" : 8176,
"indexSizes" : {
"_id_" : 8176
},
"ok" : 1
}
查看集合中所有的文檔
db.集合名稱.find();
db.userdatas.find()
{ "_id" : ObjectId("59789a56bc629e73c4f09e1c"), "name" : "wang wu", "age" : 45 }
{ "_id" : ObjectId("59789a74bc629e73c4f09e1e"), "name" : "wang wu", "age" : 8 }
{ "_id" : ObjectId("59789ac0bc629e73c4f09e20"), "name" : "wang wu", "age" : 33 }
{ "_id" : ObjectId("597f357a09c84cf58880e40e"), "name" : "u1", "age" : 37 }
文檔替換 db.集合名稱.update(條件,新的文檔);只會修改符合條件的第一個文檔。
db.test.update({"age":12},{"address":"北京","name":"老王"})
$set :指定一個字段的值,如果字段不存在,會創建一個.
db.test.update({"name":"u1"},{"$set":{"name":"u2"}},0,1)
$unset :刪掉某個字段
db.test.update({"name":"u1"},{"$unset":{"address":1}},0,1)
$push:向已有數組的末尾加入一個元素,要是沒有就新建一個數組。
db.test.update({"name":"u1"},{"$push":{"score":2}},0,1)
each:通過一次 push來操作多個值
db.test.update({"name":"u1"},{"$push":{"score":{"$each":[4,5,6]}}})
save方法
如果文檔存在就更新,不存在就新建,主要根據”_id”來判斷。
db.test.save({"name":"li si"})
update
第三個參數 0 表示查找不到,不增加一個文檔 1表示查找不到,增加文檔
第四個參數 0 表示只更新第一個 1 更新所有查找到的文檔
1:只能用在$XXX的操作中
2:最好每次都顯示的指定update的第4個參數,以防止服務器使用默認行爲
find
find(條件,顯示的字段)
db.userdatas.find({},{name:1,_id:0})
比較操作:lt, lte,gt, gte,$ne
db.userdatas.find({age:{$gte:35}})
30<=age<=35
db.userdatas.find({age:{$lte:35,$gte:30}})
$and:包含多個條件,他們之間爲and的關係
db.userdatas.find({"name":"u5",age:{$gt:33}})
db.userdatas.find({$and:[{"name":"u5"},{age:{$gt:33}}]})
$or :包含多個條件,他們之間爲or的關係 ,$nor相當於or取反
db.userdatas.find({$or:[{"name":"u5"},{age:{$gt:33}}]})
$not:用作其他條件之上,不能作爲頂級查詢,後面可跟條件,正則
db.userdatas.find({age:{$not:{$lt:35}}})
db.userdatas.find({name:{$not:/wang/}})
$mod:將查詢的值除以第一個給定的值,如果餘數等於等二個值則匹配成功。
db.userdatas.find({age:{$mod:[10,7]}})
db.userdatas.find({age:{$not:{$mod:[10,7]}}})
in:查詢一個鍵的多個值,只要鍵匹配其中一個即可, nin爲不包含
db.userdatas.find({age:{$in:[33,35]}})
db.userdatas.find({age:{$nin:[33,35]}})
$all:鍵需要匹配所有的值,用於數組
db.userdatas.find({score:{$all:[7,4]}})
$exists:檢查某個鍵是否存在,1表示存在,0表示不存在
db.userdatas.find({"score":{$exists:1}})
null類型:不僅能匹配鍵的值爲null,還匹配鍵不存在的情況
db.userdatas.find({score:null})
db.userdatas.find({name:{$in:[null],$exists:1}})
正則
MongoDB使用Perl兼容的正則表達式(PCRE),
比如: db.users.find({“name”:/sishuok/i});
又比如: db.users.find({“name”:/^sishuok/});
數組搜索
單個元素匹配,就跟前面寫條件一樣,{key:value}
db.userdatas.find({score:0})
多個元素匹配,使用$all, {key:{$all:[a,b]}},元素的順序無所謂
db.userdatas.find({score:{$all:[2,0]}})
可以使用索引指定查詢數組特定位置, {“key.索引號”:value}
db.userdatas.find({"score.0":7}) 索引從0開始
查詢某個長度的數組,使用$size
db.userdatas.find({"score":{$size:4}})
指定子集,使用$slice,正數是前面多少條,負數是尾部多少條,也可以指定偏
移量和要返回的元素數量,比如:$slice:[50,10]
db.userdatas.find({},{"score":{$slice:2}})
db.userdatas.find({},{"score":{$slice:-2}})
db.userdatas.find({},{"score":{$slice:[1,1]}})
可以使用來指定符合條件的任意一個數組元素,如:{”users. ”:1}
db.userdatas.find({"score":{$in:[7,4]}},{"score.$":1,name:1})
$elemMatch:要求同時使用多個條件語句來對一個數組元素進行比較判斷
db.userdatas.find({score:{$elemMatch:{$gt:8,$lt:12}}})
查詢內嵌文檔
1:查詢整個內嵌文檔與普通查詢是一樣的 。
2:如果要指定鍵值匹配,可以使用“.” 操作符,比如:{“name.first”:”a” ,“name.last”:”b”} 。
3:如果要正確的指定一組條件,那就需要使用$elemMatch,以實現對內嵌文檔的多個鍵進行匹配操作。
插入一個文檔:
db.userdatas.update({"name":"u2"},{$set:{wendang:{"yw":80,"xw":90}}})
查詢文檔:
db.userdatas.find({"wendang.yw":80})
查詢記錄條數的命令:count
1,直接使用count()的話,得到的是整個記錄的條數。
2,如果要獲取按條件查詢後記錄的條數,需要指定count(true 或者非0 的數)
db.userdatas.find().count()
db.userdatas.find().limit(2).count(true)
限制返回的記錄條數的命令:limit(要返回的條數)
db.userdatas.find().limit(2)
限制返回的記錄條數起點的命令:skip(從第幾條開始返回)
db.userdatas.find().skip(0).limit(2)
排序的命令:sort({要排序的字段:1爲升序,-1爲降序})
db.userdatas.find().sort({age:-1})
db.userdatas.find().sort({age:-1}).limit(2)
分頁
分頁查詢:組合使用limit,skipt和sort skip 效率低
當然也可以使用其他方式來分頁,比如採用自定義的id,然後根據id來分頁
查詢給定鍵的所有不重複的數據,命令:distinct
語法:db.runCommand({“distinct”:集合名,“key”:”獲得不重複數據的字段”});
db.runCommand({"distinct":"userdatas","key":"age"})
db.runCommand({"distinct":"userdatas","key":"age"})
{
"waitedMS" : NumberLong(0),
"values" : [
45,
8,
33,
37,
78,
32,
30,
20
],
"stats" : {
"n" : 11,
"nscanned" : 0,
"nscannedObjects" : 11,
"timems" : 0,
"planSummary" : "COLLSCAN"
},
"ok" : 1
}
遊標
1:獲取遊標,示例如下:
var c = db.users.find();
2:循環遊標,可以用集合的方式,示例如下:
while(c.hasNext()){
printjson(c.next().文檔鍵);
}
3:也可以使用forEach來循環,示例如下:
c.forEach(function(obj){
print(obj);
});