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的区别是$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)

相关推荐

  • 详解MongoDB的条件查询和排序

    目录 find 方法 条件组合 比较操作符 IN 查询 限制返回结果条数和跳过数据 排序 总结 find 方法 查询的基本格式是db.collection.find({条件}),其中条件是可选的,类似于 MySQL 的 WHERE 条件一样.示例如下: // 查找全部文档 db.collection.find({}); // 查找指定条件的文档 db.collection.find({key: value}); // 查找昵称为岛上码农的用户 db.users.find({nickname: '

  • MongoDB数据库条件查询技巧总结

    目录 前言 连接数据库 查看数据仓库 查看数据库表 查看数据表内容 查询方式 总结 前言 今天不讨论使用自带 UI 界面的连接工具,仅讨论使用命令行查询 MongoDB 数据库的情况.在排查问题的时候,很多时候直接使用命令行更加方便.但是有一个前提,我们必须首先掌握 MongoDB 数据库命令行常用命令才行,本文以条件查询为例进行介绍. 连接数据库 首先,使用命令行连接数据库,命令如下: mongo 127.0.0.1:27017 输出如下结果表示连接成功: 查看数据仓库 查看数据仓库列表,命令

  • MongoDB的查询方法

    代码: db.blogs.insert([ { "author": "张三", "title": "MongoDB简介", "content": "它是介于关系型数据库和非关系型数据库之间的一种NoSQL数据库,用C++编写,是一款集敏捷性.可伸缩性.扩展性于一身的高性能的面向文档的通用数据库", "tags": [ "MongoDB", &quo

  • MongoDB 查询操作的实例详解

    MongoDB 查询操作的实例详解 使用find或findOne进行查询.并可以进行范围查询.数据集查询.不等式查询,以及其他的一些查询. 查询将会返回DBcursor 游标只有在你需要的时候返回文档 针对游标返回的文档(结果集) 进行操作 例如:忽略一定数量的结果,或者返回结果的数量,以及对结果的排序. 1.指定需要返回的键 有时候仅仅对文档的某几个键值感兴趣,可以屏蔽返回的不感兴趣的键值,返回感兴趣的键值 mongos> db.blog.find({},{"name":1})

  • 常用的MongoDB查询语句的示例代码

    背景 最近做了几个规则逻辑.用到mongo查询比较多,就是查询交易信息跑既定规则筛选出交易商户,使用聚合管道进行统计和取出简单处理后的数据,用SQL代替业务代码逻辑的判断. 方法 MongoDB聚合使用aggregate,聚合管道采取自动向下子执行方式,基本语法格式: db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION) 聚合框架中常用的操作: $project:修改输入文档的结构.可以用来重命名.增加或删除域,也可以用于创建计算结果以及嵌套文档.

  • MongoDB的一些常用查询方法

    Query.All("name", "a", "b");//通过多个元素来匹配数组 Query.And(Query.EQ("name", "a"), Query.EQ("title", "t"));//同时满足多个条件 Query.EQ("name", "a");//等于 Query.Exists("type"

  • MongoDB数据查询方法干货篇

    本文主要给大家介绍了MongoDB数据查询的相关内容,对大家具有一定的参考价值,需要的朋友们一起来学习学习吧. 导入测试数据 在开始之前我们应该先准备数据方便演示,这里我插入的了几条数据,数据如下: db.user.insertMany( [{ name:'jack', age:22, sex:'Man', tags:['python','c++','c'], grades:[22,33,44,55], school:{ name:'shida', city:'xuzhou' } },{ nam

  • MongoDB多条件模糊查询示例代码

    前言 模糊查询是数据库的基本操作之一,实现对给定的字符串是否与指定的模式进行匹配.如果字符完全匹配,可以用=等号表示,如果部分匹配可认为是一种模糊查询.在关系型数据中,通过SQL使用like '%fens%'的语法.那么在mongodb中我们应该如何实现模糊查询的效果呢. 查询条件 关键字 说明 $or 或关系 $nor 或关系取反 $gt 大于 $gte 大于等于 $lt 小于 $lte 小于等于 $ne 不等于 $in 在多个值范围内 $nin 不在多个值范围内 $all 匹配数组中多个值

  • MongoDB查询之高级操作详解(多条件查询、正则匹配查询等)

    MongoDB查询之高级操作 语法介绍 MongoDB查询文档使用find()方法,同时find()方法以非结构化的方式来显示所有查询到的文档. -- 1.基本语法 db.collection.find(query, projection) -- 返回所有符合查询条件的文档 db.collection.findOne(query, projection) -- 返回第一个符合查询条件的文档 -- query:可选,查询条件操作符,用于指定查询条件 -- projection:可选,投影操作符,用

  • MongoDB基础之查询文档

    目录 一.查询文档 实例 二.条件操作符 MongoDB 与 RDBMS Where 语句比较 举例:使用 (<) 和 (>) 查询 - $lt 和 $gt 三.AND 条件 四.OR 条件 五.AND 和 OR 联合使用 六.$type 操作符 描述 七.Limit与Skip方法 Limit() 方法 Skip() 方法 实例 八.排序 九.聚合 管道的概念 一.查询文档 MongoDB 查询文档使用 find() 方法.以非结构化的方式来显示所有文档. MongoDB 查询数据的语法格式如

随机推荐