mongoDB的Find詳解、分頁和排序、遊標
1.指定返回的鍵
db.[documentName].find ({條件},{鍵指定})
資料準備persons.json
var persons = [{
name:"jim",
age:25,
email:"[email protected]",
c:89,m:96,e:87,
country:"USA",
books:["JS","C++","EXTJS","MONGODB"]
},
{
name:"tom",
age:25,
email:"[email protected]",
c:75,m:66,e:97,
country:"USA",
books:["PHP","JAVA","EXTJS","C++"]
},
{
name:"lili",
age:26,
email:"
c:75,m:63,e:97,
country:"USA",
books:["JS","JAVA","C#","MONGODB"]
},
{
name:"zhangsan",
age:27,
email:"[email protected]",
c:89,m:86,e:67,
country:"China",
books:["JS","JAVA","EXTJS","MONGODB"]
},
{
name:"lisi",
age:26,
email:"[email protected]",
c:53,m:96,e:83,
country:"China",
books:["JS","C#","PHP","MONGODB"]
},
{
name:"wangwu",
age:27,
email:"
c:45,m:65,e:99,
country:"China",
books:["JS","JAVA","C++","MONGODB"]
},
{
name:"zhaoliu",
age:27,
email:"[email protected]",
c:99,m:96,e:97,
country:"China",
books:["JS","JAVA","EXTJS","PHP"]
},
{
name:"piaoyingjun",
age:26,
email:"[email protected]",
c:39,m:54,e:53,
country:"Korea",
books:["JS","C#","EXTJS","MONGODB"]
},
{
name:"lizhenxian",
age:27,
email:"
c:35,m:56,e:47,
country:"Korea",
books:["JS","JAVA","EXTJS","MONGODB"]
},
{
name:"lixiaoli",
age:21,
email:"[email protected]",
c:36,m:86,e:32,
country:"Korea",
books:["JS","JAVA","PHP","MONGODB"]
},
{
name:"zhangsuying",
age:22,
email:"[email protected]",
c:45,m:63,e:77,
country:"Korea",
books:["JS","JAVA","C#","MONGODB"]
}]
for(var i = 0;i<persons.length;i++){
db.persons.insert(persons[i])
}
1.1 查詢出所有資料的指定鍵(name ,age ,country)
db.persons.find({},{name:1,age:1,country:1,_id:0})
2.查詢條件
2.查詢條件
2.1查詢出年齡在25到27歲之間的學生
db.persons.find({age: {$gte:25,$lte:27},{_id:0,age:1})
2.2查詢出所有不是韓國籍的學生的數學成績
db.persons.find({country:{$ne:”Korea”}},{_id:0,m:1})
3.包含或不包含
$in或$nin
2.3查詢國籍是中國或美國的學生資訊
db.persons.find({country:{$in:[“USA”,“China”]}})
2.4查詢國籍不是中國或美國的學生資訊
db.persons.find({country:{$nin:[“USA”,“China”]}})
4.OR查詢
$or
2.4查詢語文成績大於85或者英語大於90的學生資訊
db.persons.find({$or:[{c:{$gte:85}},{e:{$gte:90}}]},{_id:0,c:1,e:1})
5.Null
把中國國籍的學生上增加新的鍵sex
db.person.update({country:”China”},{$set:{sex:”m”}},false,true)
2.5查詢出sex 等於 null的學生
db.persons.find({sex:{$in:[null]}},{country:1})
6.正則查詢
2.6查詢出名字中存在”li”的學生的資訊
db.persons.find({name:/li/i},{_id:0,name:1})
7.$not的使用
$not可以用到任何地方進行取反操作
2.7查詢出名字中不存在”li”的學生的資訊
db.persons.find({name:{$not:/li/i}},{_id:0,name:1})
$not和$nin的區別是$not可以用在任何地方兒$nin是用到集合上的
8.陣列查詢$all和index應用
2.8查詢喜歡看MONGOD和JS的學生
db.persons.find({books:{$all:[“MONGOBD”,”JS”]}},{books:1,_id:0})
2.9查詢第二本書是JAVA的學習資訊
db.persons.find({“books.1”:”JAVA”})
9.查詢指定長度陣列$size它不能與比較查詢符一起使用(這是弊端)
2.8查詢出喜歡的書籍數量是4本的學生
db.persons.find({books:{$size:4}},{_id:0,books:1})
2.9查詢出喜歡的書籍數量大於3本的學生
1.增加欄位size
db.persons.update({},{$set:{size:4}},false,true)
2.改變書籍的更新方式,每次增加書籍的時候size增加1
db.persons.update({查詢器},{$push:{books:”ORACLE”},$inc:{size:1}})
3.利用$gt查詢
db.persons.find({size:{$gt:3}})
2.10利用shell查詢出Jim喜歡看的書的數量
var persons = db.persons.find({name:"jim"})
while(persons.hasNext()){
obj = persons.next();
print(obj.books.length)
}
課間小結
1.mongodb 是NOSQL資料庫但是他在文件查詢上還是很強大的
2.查詢符基本是用到花括號裡面的更新符基本是在外面
3.shell是個徹徹底底的JS引擎,但是一些特殊的操作要靠他的
各個驅動包來完成(JAVA,NODE.JS)
10.$slice操作符返回文件中指定陣列的內部值
2.11查詢出Jim書架中第2~4本書
db.persons.find({name:"jim"},{books:{"$slice":[1,3]}})
2.12查詢出最後一本書
db.persons.find({name:"jim"},{books:{"$slice":-1},_id:0,name:1})
11.文件查詢
為jim新增學習簡歷文件 jim.json
var jim = [{
school :"K",
score:"A"
},{
school :"L",
score:"B"
},{
school :"J",
score:"A+"
}]
db.persons.update({name:"jim"},{$set:{school:jim}})
2.13查詢出在K上過學的學生
1. 這個我們用絕對匹配可以完成,但是有些問題(找找問題?順序?總要帶著score?)
db.persons.find({school:{school:"K",score:"A"}},{_id:0,school:1})
2.為了解決順序的問題我可以用物件”.”的方式定位
db.persons.find({"school.score":"A","school.school":"K"},{_id:0,school:1})
3.這樣也問題看例子:
db.persons.find({"school.score":"A","school.school":”J”},{_id:0,school:1})
同樣能查出剛才那條資料,原因是score和school會去其他物件對比
4.正確做法單條條件組查詢$elemMatch
db.persons.find({school:{$elemMatch:{school:"K",score:"A"}}})
12.$where
12.查詢年齡大於22歲,喜歡看C++書,在K學校上過學的學生資訊
複雜的查詢我們就可以用$where因為他是萬能
但是我們要儘量避免少使用它因為他會有效能的代價
db.persons.find({"$where":function(){
var books = this.books;
var school = this.school;
if(this.age > 22){
var php = null;
for ( var i = 0; i < books.length; i++) {
if(books[i] == "C++"){
php = books[i];
if(school){
for (var j = 0; j < school.length; j++) {
if(school[j].school == "K"){
return true;
}
}
break;
}
}
}
}
}})
二、分頁和排序
1.Limit返回指定的資料條數
1.1查詢出persons文件中前5條資料
db.persons.find({},{_id:0,name:1}).limit(5)
2.Skip返回指定資料的跨度
2.1查詢出persons文件中5~10條的資料
db.persons.find({},{_id:0,name:1}).limit(5).skip(5)
3.Sort返回按照年齡排序的資料[1,-1]
db.persons.find({},{_id:0,name:1,age:1}).sort({age:1})
注意:mongodb的key可以存不同型別的資料排序就也有優先順序
最小值
null
數字
字串
物件/文件
陣列
二進位制
物件ID
布林
日期
時間戳->正則 ->最大值4.Limit和Skip完成分頁
4.1三條資料位一頁進行分頁
第一頁:db.persons.find({},{_id:0,name:1}).limit(3).skip(0)
第二頁:db.persons.find({},{_id:0,name:1}).limit(3).skip(3)
4.2skip有效能問題,沒有特殊情況下我們也可以換個思路
對文件進行重新解構設計
每次查詢操作的時候前後臺傳值全要把上次的最後一個文件的日期儲存下來
db.persons.find({date:{$gt:日期數值}}).limit(3)
個人建議:應該把軟體的重點放到便捷和精確查詢上而不是分頁的效能上
因為使用者最多不會翻查過2頁的
三、遊標
利用遊標遍歷查詢資料
var persons = db.persons.find();
while(persons.hasNext()){
obj = persons.next();
print(obj.name)
}
2.遊標幾個銷燬條件
1.客戶端發來資訊叫他銷燬
2.遊標迭代完畢
3.預設遊標超過10分鐘沒用也會別清除
3.查詢快照
快照後就會針對不變的集合進行遊標運動了,看看使用方法.
db.persons.find({$query:{name:”Jim”},$snapshot:true})
高階查詢選項
$query
$orderby
$maxsan:integer最多掃描的文件數
$min:doc 查詢開始
$max:doc 查詢結束
$hint:doc 使用哪個索引
$explain:boolean 統計
$snapshot:boolean一致快照
我們從MongoDB中獲取到資料後,通常會執行這種操作:對文件進行處理後,即時地更新到資料庫中。這時對於大量文件的情況有可能產生一個問題,當我們用遊標遍歷一個文件時,假設我們增大了其大小,並且超高了MongoDB為文件設定的預留區域,這時我們將這條文件更新到資料庫中,資料庫沒法將其放置在其原始位置上,只能將其移動,通常會移動到集合末尾!這樣我們再次獲取文件時,有可能又得到這條以被修改的文件!!
應對這個問題,我們的方法就是對查詢結果進行快照!如果使用了上面提到的“$snapshop”選項,查詢就是針對不變的集合檢視執行的!這點我們只是描述一下,實際情況中可以不用擔心了,因為MongoDB中,所有返回一組的查詢實際都進行了快照!