当前位置: 代码网 > it编程>数据库>Nosql > MongoDB实现查询、分页和排序操作以及游标的使用

MongoDB实现查询、分页和排序操作以及游标的使用

2024年05月19日 Nosql 我要评论
一、find查询事前准备:插入如下数据db.students.insert([{ _id:1, name:"zhao", age:25, country:"usa", books:["js","c+

一、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的区别是$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.游标几个销毁条件  

客户端发来信息叫他销毁

游标迭代完毕

默认游标超过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实现查询操作的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com