MongoDB實現查詢、分頁和排序操作以及游標的使用
一、Find查詢
事前準備:插入如下數據
db.Students.insert([
{ _id:1, name:"Zhao", age:25, country:"USA", books:["JS","C++","EXTJS","MONGODB"]},
{ _id:2, name:"Qian",age:22, country:"USA", books:["PHP","JAVA","EXTJS","C++"]},
{ _id:3,name:"Sun",age:26, country:"USA", books:["JS","JAVA","C#","MONGODB"]},
{ _id:4, name:"Li",age:27,country:"China",books:["JS","JAVA","EXTJS","MONGODB"]},
{ _id:5,name:"Zhou", age:30,country:"China",books:["JS","C#","PHP","MONGODB"]},
{ _id:6, name:"Wu", age:27, country:"Japan", books:["JS","JAVA","C++","MONGODB"]},
{ _id:7, name:"Zheng", age:27, country:"UK", books:["JS","JAVA","EXTJS","PHP"]},
{ _id:8, name:"Wang", age:26, country:"Korea",books:["JS","C#","EXTJS","MONGODB"]}
]) 1.指定返回的鍵
db.[文檔名].find ({條件},{鍵指定})
查詢出所有數據的指定鍵(name ,age ,country)
db.Students.find({},{name:1,age:1,country:1,_id:0})- ※條件不寫就是查詢全部
- ※需要查詢的就在鍵后指定為1,不用就指定為0(感覺只要想查的鍵后面有值不見得非得是1)
- ※如果不指定顯示=式_id:0,那查詢過程都是帶有_id的
2.查詢條件
比較操作符 | 意義 | 舉例 |
|---|---|---|
$lt | < | 查詢出id小于5的學生 > db.Students.find({_id:{$lt:5}},{}) |
$lte | <= | 查詢出年齡小于等于25歲之間的學生 > db.Students.find({age:{$lte:25}},{}) |
$ne | != | 查詢出國家不是中國的學生 > db.Students.find({country:{$ne:"China"}},{}) |
$gt | > | 查詢所有年紀大于27歲的,中國學生名字 > db.Students.find({age:{$gt:27}},{name:1,country:1,age:1}) { "_id" : 5, "name" : "Zhou", "age" : 30, "country" : "China" } |
$gte | >= | 同上 |
3.包含或不包含
較操作符 | 意義 | 舉例 |
|---|---|---|
$in | 包含 | 查詢國家是中國和美國的學生 > db.Students.find({country:{$in:["China","USA"]}},{}) |
$nin | 不包含 | 查詢年齡不是27歲的學生 > db.Students.find({age:{$nin:[27]}},{}) |
4.OR查詢
較操作符 | 意義 | 舉例 |
|---|---|---|
$or | 包含 | 查詢年齡小于27歲,或者國家是美國的學生 >db.Students.find({$or:[{age:{$lt:27}},{country:"USA"}]},{}) 查詢年齡大于等于30歲,或者國家是不是美國的學生 >db.Students.find({$or:[{age:{$gte:30}},{country:{$nin:["China"]}}]},{}) |
5.Null
為所有美國學生添加性別屬性為男性(M)
> db.Students.update({country:"USA"},{$set:{sex:"M"}},false,true)查詢所有sex屬性為null的學生
> db.Students.find({sex:{$in:[null]}},{name:1,country:1})6.正則查詢
查詢出名字中存在”Zh”的學生的信息
> db.Students.find({name:/Zh/},{})
{ "_id" : 1, "name" : "Zhao", "age" : 25, "country" : "USA", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ], "sex" : "M" }
{ "_id" : 5, "name" : "Zhou", "age" : 30, "country" : "China", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "_id" : 7, "name" : "Zheng", "age" : 27, "country" : "UK", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }7.$not的使用
※$not和$nin的區(qū)別是$not可以用在任何地方兒$nin是用到集合上的
查找出名字中不存在“Zh”的學生信息
> db.Students.find({name:{$not:/Zh/}},{})
{ "_id" : 2, "name" : "Qian", "age" : 22, "country" : "USA", "books" : [ "PHP","JAVA", "EXTJS", "C++" ], "sex" : "M" }
{ "_id" : 3, "name" : "Sun", "age" : 26, "country" : "USA", "books" : [ "JS", "JAVA", "C#", "MONGODB" ], "sex" : "M" }
{ "_id" : 4, "name" : "Li", "age" : 27, "country" : "China", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "_id" : 6, "name" : "Wu", "age" : 27, "country" : "Japan", "books" : [ "JS", "JAVA", "C++", "MONGODB" ] }
{ "_id" : 8, "name" : "Wang", "age" : 26, "country" : "Korea", "books" : [ "JS","C#", "EXTJS", "MONGODB" ] }8.數組查詢$all和index應用
查詢所有擁有JS和PHP書籍的同學
> db.Students.find({books:{$all:["JS","PHP"]}},{})
{ "_id" : 5, "name" : "Zhou", "age" : 30, "country" : "China", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "_id" : 7, "name" : "Zheng", "age" : 27, "country" : "UK", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }查詢第三本書是C#的同學
> db.Students.find({"books.2":"C#"},{})
{ "_id" : 3, "name" : "Sun", "age" : 26, "country" : "USA", "books" : [ "JS", "JAVA", "C#", "MONGODB" ], "sex" : "M" } 上面那個使用index來查詢的例子中,"books.2"一定要用""包含起來
9.查詢指定長度數組$size
它不能與比較查詢符一起使用(這是弊端)
插入一條book數組有兩本數的同學
> db.Students.insert({_id:9,name:"Xu",age:26,country:"Japan",books:["C#","PHP"]})
WriteResult({ "nInserted" : 1 })查詢只有兩本書的同學
> db.Students.find({books:{$size:2}},{})
{ "_id" : 9, "name" : "Xu", "age" : 26, "country" : "Japan", "books" : [ "C#", "PHP" ] }查詢名字是“Li”的喜歡的書的數量
> var person = db.Students.find({name:"Li"})
> while(person.hasNext()){ obj = person.next(); print(obj.books.length) }10.$slice操作符返回文檔中指定數組的內部值
查詢名字為“Wang”書架中第1~3本書
> db.Students.find({name:"Wang"},{books:{$slice:[0,3]}})
{ "_id" : 8, "name" : "Wang", "age" : 26, "country" : "Korea", "books" : [ "JS", "C#", "EXTJS" ] }查詢出最后一本書
> db.Students.find({name:"Wang"},{books:{$slice:-1}})
{ "_id" : 8, "name" : "Wang", "age" : 26, "country" : "Korea", "books" : [ "MONGODB" ] } 11.文檔查詢
添加一個對象數組到“Li”同學,記錄“Li”同學的成績
> var li = [{
... subject :"Math",
... score: 90
... },{
... subject :"English",
... score:85
... },{
... subject :"History",
... score:95
... }]
> db.Students.update({name:"Li"},{$set:{school:li}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.Students.find({name:"Li"},{})
{ "_id" : 4, "name" : "Li", "age" : 27, "country" : "China", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ],
"school" : [{ "subject" : "Math", "score" : 90 },{ "subject" : "English", "score" : 85 }, { "subject" : "History", "score" : 95 }]
}
>查詢參加了數學考試,并且分數為90的同學
①.絕對匹配可以
> db.Students.find({school:{subject:"Math",score:90}},{_id:0,name:1})
{ "name" : "Li" } 但是問題存在如下:
條件順序變化時候,
> db.Students.find({school:{score:90,subject:"Math"}},{_id:0,name:1})
> --查不到東西--條件數目不一致的時候,也同樣查不到
②.為了解決順序的問題我可以用對象“.”
> db.Students.find({"school.subject":"Math","school.score":90},{name:1})
{ "_id" : 4, "name" : "Li" }這種方式支持順序的變化,但是也同樣存在問題,那就是匹配的問題,條件不是作為一對條件來進行匹配的
例如:
> db.Students.find({"school.subject":"Math","school.score":85},{name:1})
{ "_id" : 4, "name" : "Li" } 這里的85分是英語成績
③.正確做法單條條件組查詢$elemMatch
> db.Students.find({school:{$elemMatch:{subject:"Math",score:90}}},{name:1})
{ "_id" : 4, "name" : "Li" }
> db.Students.find({school:{$elemMatch:{score:90,subject:"Math"}}},{name:1})
{ "_id" : 4, "name" : "Li" }
> db.Students.find({school:{$elemMatch:{subject:"Math"}}},{name:1})
{ "_id" : 4, "name" : "Li" }
>二、分頁與排序
1.Limit返回指定的數據條數
查詢出Student文檔中前5條數據
> db.Students.find().limit(5)
2.Skip返回指定數據的跨度
查詢出persons文檔中3~8條的數據
> db.Students.find().limit(5).skip(2)
3.Sort返回按照年齡排序的數據[1,-1]
查詢所有數據,按照年齡排序
正序
> db.Students.find({},{_id:0,age:1,name:1}).sort({age:1})
{ "name" : "Qian", "age" : 22 }
{ "name" : "Zhao", "age" : 25 }
{ "name" : "Sun", "age" : 26 }
{ "name" : "Wang", "age" : 26 }
{ "name" : "Xu", "age" : 26 }
{ "name" : "Wu", "age" : 27 }
{ "name" : "Zheng", "age" : 27 }
{ "name" : "Li", "age" : 27 }
{ "name" : "Zhou", "age" : 30 }倒序
> db.Students.find({},{_id:0,age:1,name:1}).sort({age:-1})
{ "name" : "Zhou", "age" : 30 }
{ "name" : "Wu", "age" : 27 }
{ "name" : "Zheng", "age" : 27 }
{ "name" : "Li", "age" : 27 }
{ "name" : "Sun", "age" : 26 }
{ "name" : "Wang", "age" : 26 }
{ "name" : "Xu", "age" : 26 }
{ "name" : "Zhao", "age" : 25 }
{ "name" : "Qian", "age" : 22 }
>skip性能不好,可以采用插入時間的做法來彌補,具體方法如下:
- 1.在每一個記錄后面都加入一個插入時間的鍵值對
- 2.每次取數據的時候都把取出的最后一個數據的時間保存下來,再傳給下一次查詢
- 3.使用db.persons.find({date:{$gt:日期數值}}).limit(取出的數據數目)比較查詢取出要分頁的數據
三、游標和其他知識
1.利用游標來查詢數據
var persons = db.persons.find();
while(persons.hasNext()){
obj = persons.next();
print(obj.name)
}2.游標幾個銷毀條件
客戶端發(fā)來信息叫他銷毀
游標迭代完畢
默認游標超過10分鐘沒用也會別清除
3.查詢快照
快照后就會針對不變的集合進行游標運動了,看看使用方法.
db.persons.find({$query:{name:”Jim”},$snapshot:true})為什么用快照,以為MongoDB在進行更新的時候,例如添加一些鍵值對,那么MongoDB的處理不會在原來的索引位置上進行更新操作,而是會把
更新之后的數據,放在末尾,那么就導致了前后兩次進行查詢時候相同索引對應不同數據的情況
補充:
高級查詢選項
- $where
- $query
- $orderby
- $maxsan:integer 最多掃描的文檔數
- $min:doc 查詢開始
- $max:doc 查詢結束
- $hint:doc 使用哪個索引
- $explain:boolean 統(tǒng)計
- $snapshot:boolean 一致快照
到此這篇關于MongoDB實現查詢操作的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
關于MongoTemplate通過id查詢?yōu)閚ull的問題
這篇文章主要介紹了關于MongoTemplate通過id查詢?yōu)閚ull的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01
mongodb 修改器($inc/$set/$unset/$push/$pop/upsert)
對于文檔的更新除替換外,針對某個或多個文檔只需要部分更新可使用原子的更新修改器,能夠高效的進行文檔更新。更新修改器是中特殊的鍵2017-04-04

