實驗目的:
(1)掌握MongoDB中數據查詢的方法;
(2)掌握MongoDB中索引及其創建;
實驗內容:
一、 MongoDB中數據查詢的方法;
(1)find函數的使用;
(2)條件操作符:exists判斷字段是否存在、null值處理、$mod取模運算、不等於、包含、不包含、數組元素個數、限制返回、排序、分頁、隨機顯示。
(3)distinct找出給定鍵所有不同的值;
(4)group分組;
(5)遊標;
(6)存儲過程。
二、 MongoDB中索引及其創建;
(1)基礎索引;
(2)文檔索引;
(3)組合索引;
(4)唯一索引;
(5)強制使用索引;
(6)擴展索引;
(7)刪除索引
(8)explain執行計劃
一、MongoDB中數據查詢的方法
(1). find函數的使用
db.student.find() 查詢所有數據
(2). 條件操作符
$all匹配所有、
db.student.find({sex:{$all:['male']}})
查詢男生的學生數據
$exists判斷字段是否存在
> db.student.find({class: {$exists:true}})
查詢所有擁有class字段的學生信息;如果exists:false
,表示不存在這個字段的信息。
null值處理
teacher集合中,_id=1的數據沒有字段age,或者說age字段對應的值是null,所以可以進行null值處理,將他查出來。
db.teacher.find({age:null})
$mod取模運算
例如:找出teacher集合中年齡age對10取模等於1的人的數據。
db.teacher.find({age:{$mod:[10,1]}})
運算符:
- $gt 大於
- $gte 大於等於
- $lt 小於
- $lte 小於等於
- $ne 不等於
- $in 包含
- $nin 不包含
- $eq 等於
查詢學生年齡大於22的數據
db.student.find({age:{$gt:22}})
查詢學生年齡小於22的數據
db.student.find({age:{$lt:22}})
查詢學生年齡等於22的數據
db.student.find({age:{$eq:22}})
數組元素個數
db.student.count()
#查出student集合中的記錄數
db.student.find({sex:'male'}).count()
#查出student集合中sex=male的人數
限制返回
db.student.find({},{sname:1}) # 返回sname字段其餘不返回(id也返回)
db.student.find({},{sname:0}) # 除sname字段不返回外,其餘都返回。
排序
按照年齡從大到小的順序給學生表排序
db.student.find().sort({age:-1})
從小到大的順序排序
db.student.find().sort({age:1})
分頁
例如取前兩條數據做分頁。(如果想從後往前取數據,那麼數字前加負號 ’ - ’)
db.student.find().limit(2)
隨機顯示
db.student.aggregate([ { $sample: { size: N } } ] )
從學生表中隨機取出N條數據。
(3)distinct找出給定鍵所有不同的值;
db.student.distinct(‘sname’) #找出不同的名字
(4)group分組
求出年齡總和
db.student.aggregate( [
{
$group: {
_id: null,
total: { $sum: "$age" }
}
}
] )
求學生的平均年齡
db.student.aggregate([
{
$group: {
_id: null,
total: { $avg: "$age" }
}
}
])
(5)遊標;
定義遊標
var mycursor = db.student.find()
打印結果
while(mycursor.hasNext()){
printjson(mycursor.next());
}
也可以使用遊標的forEach(printjson); 迭代訪問文檔.
顯示遊標狀態信息
> db.serverStatus().metrics.cursor
{
"timedOut" : NumberLong(0),
"open" : {
"noTimeout" : NumberLong(0),
"pinned" : NumberLong(0),
"total" : NumberLong(0)
}
}
- timedOut:自服務器器啓動以來超時遊標數;
- noTimeout:使用DBQuery.Option.noTimeout 選項防止超時打開的遊標數;
- pinned :打開的遊標數量;
- total:打開遊標的總數量;
關閉不活躍的遊標
如果一個遊標還沒有遍歷完,但是不使用了,需要將該遊標關閉。默認情況下,服務器會自動關閉超過10分鐘活躍的遊標和還未耗盡的遊標。你也可以自己手動關閉。
手動關閉前:var mycursor = db.student.find().noCursorTimeout();
然後在 cursor.close()
(6)存儲過程。
MongoDB 存儲過程是存儲在 db.system.js 表中的.
1、 添加存儲過程
db.system.js.save
(
{
_id:"getStuCount",
value:function(){
return db.student.find().count();
},
description:"獲取總數"
}
)
執行存儲過程:var obj = db.eval(“getStuCount()”);
2、 查詢存儲過程
db.system.js.find();
3、 修改存儲過程
先添加一個add的存儲過程
db.system.js.save({_id:“add”,value:function(x,y){return x+y;}})
修改add存儲過程:
db.system.js.update(
{_id:"add"},
{$set:{value:function(x,y,z){return x+y+z;}}}
);
db.loadServerScripts()
:重新加載存儲過程
查看存儲過程,並執行
4、 刪除存儲過程
db.system.js.remove({_id:‘getStuList’});
MongoDB中索引及其創建
先向orders文檔中添加數據
db. orders.insert({
"onumber" : i,
"date" : "2020-06-09",
"cname" : "hht"+i,
"items" :[ {
"ino" : i,
"quantity" : i,
"price" : 4.0
},{
"ino" : i+1,
"quantity" : i+1,
"price" : 6.0
}
]
})
(1)基礎索引;
默認索引:創建文檔的時候,沒有指定_id的值,MongoDB會自動創建一個ObjectId,並將一個索引創建在 _id 鍵上,默認索引的名稱是“_id”,並且無法刪除。
db.orders.getIndexes()
查看orders文檔的索引信息
單鍵索引:對文檔的某個字段創建單建索引
db.orders.createIndex({cname:1})
{
“createdCollectionAutomatically” : false,
“numIndexesBefore” : 1,
“numIndexesAfter” : 2,
“ok” : 1
}
索引名默認是cname_1
(2)文檔索引;
單列內嵌文檔索引。
db.orders.createIndex({“item.info”:1})
查看索引
(3)組合索引;
創建組合索引
db.orders.createIndex({cname:1,onumber:-1})
(4)唯一索引;
給orders文檔中的onumber字段添加上唯一索引。
db.orders.createIndex({onumber:1},{unique:true})
查看索引信息
(5)強制使用索引;
在find()後加上 hint可以強制使用某個索引。
db.orders.find({“cname”:{$gt:“hht1000”},“onumber”:2000}).hint({onumber:1})
這裏是強制使用 onumber字段上的索引。
對這個查詢執行explain()
db.orders.find({"cname":{$gt:"hht1000"},"onumber":2000}).hint({onumber:1}).explain()
(6)擴展索引;
在建立複合索引的有關字段順序的擴展
如果我們的查詢語句需要對a進行排序,對b用於覆蓋索引,那就建(a,b)索引;
如果我們的查詢語句需要對b進行排序,對a用於覆蓋索引,那就建(b,a)索引;
如果我們的查詢語句需要對a和b進行排序,那a,b哪個在前都可以用上索引。
(7)刪除索引
刪除索引,按照指定索引名刪除
> db.orders.dropIndex("cname_1")
{ "nIndexesWas" : 2, "ok" : 1 }
刪除全部索引
db.orders.dropIndexes()
(8)explain執行計劃