插入一条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.游标几个销毁条件
客户端发来信息叫他销毁
游标迭代完毕
默认游标超过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 统计
- $snapshot:boolean 一致快照
到此这篇关于MongoDB实现查询操作的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。