简述

通俗的说,游标不是查询结果,可以理解为数据在遍历过程中的内部指针,其返回的是一个资源,或者说数据读取接口.

客户端通过对游标进行一些设置就能对查询结果进行有效地控制,如可以限制查询得到的结果数量、跳过部分结果、或对结果集按任意键进行排序等!

直接对一个集合调用find()方法时,我们会发现,如果查询结果超过二十条,只会返回二十条的结果,这是因为Mongodb会自动递归find() 返回的游标。

基本操作

当我们使用一个变量来保存 find()的返回值时,其将不会自动进行遍历显示查询结果的操作,并没有真正的去查询数据库,只要当用到的时候(也就是遍历游标的时候)才会到数据库中将数据取出来,和PHP链接mysql资源一样:

php代码

$result = mysql_query('select * from message'); //返回的是一个资源

$row=mysql_fetch_assoc($result);//返回sql查询的数组(仅为满足条件的第一条),其内部就有一个指针游标,可以通过循环反复的取出数据

while($f=mysql_fetch_assoc($result)){//每循环一次游标就前进一次,游标走到尾的时候,就不返回值了
$row[]=$f;
}
var_dump($row);

mongoDB代码(js)


// while循环
var cursor = db.goods.find({goods_id:{$lte:20}},{_id:0,goods_id:1}); //使用变量来保存游标
while(cursor.hasNext()){ //cursor.hasNext()判断游标是否取到尽头
printjson(cursor.next()); //cursor.next()取出游标的下1个单元(从0开始游),注意print打印的是二进制对象,printjson打印出来的才是可阅读的json格式数据
} // for循环
var cursor = db.goods.find({goods_id:{$lte:100}},{_id:0,goods_id:1}); //使用变量来保存游标
for (;cursor.hasNext();) { //由于cursor.hasNext()自动判断的特性这里的for循环可以很简单
printjson(cursor.next());
} //forEach循环
var cursor = db.goods.find({goods_id:{$lte:100}},{_id:0,goods_id:1,goods_name:1});
var callback = function(obj){ //obj就是查出的文档对象
printjson(obj.goods_id) //直接取出goods_id的值;
}
cursor.forEach(callback);

游标在分页中的应用 limit,skip,sort

比如查到10000行,跳过100页,取10行.一般地,我们假设每页N行, 当前是page页,就需要跳过前 (page-1)*N 行, 再取N行, 在mysql中, limit offset,N来实现

在mongo中,用skip(), limit()函数来实现的,当获得游标后,我们可以先对游标进行处理后,再让访问数据库的动作按照我们的意愿发生。在这里我们就可以使用limit,skip,sort三个函数来处理游标。同时这三个函数可以组成方法链式调用的形式。

limit:限制游标返回的数量,指定了上限
skip:忽略前面的部分文档,如果文档总数量小于忽略的数量,则返回空集合
sort:得到的子集合进行排序,可以按照多个键进行正反排序!
# 查询5条
> var cursor = db.goods.find({},{_id:0,goods_id:1}).limit(5); //注意,再次使用游标的时候,游标得重置,因为使用过一次就游到最后了;
> cursor.forEach(function(obj){print(obj.goods_id);}) # 查询5条,并按照shop_price的降序排列
> var cursor = db.goods.find({},{_id:0,goods_id:1,shop_price:1}).limit(5).sort({shop_price:-1})
> cursor.forEach(function(obj){
print(obj.goods_id+' '+obj.shop_price)
})
22 5999
23 3700
32 3010
18 2878
14 2625 # 每页10条取第二页,并且升序排列
var cursor = db.goods.find({},{_id:0,goods_id:1,shop_price:1}).limit(10).sort({goods_id:1}).skip(10)
cursor.forEach(function(obj){
print(obj.goods_id+' '+obj.shop_price)
}) # 一次性打印所有的行,以易读的模式
var cursor = db.goods.find({},{_id:0,goods_id:1,shop_price:1});
printjson(cursor.toArray()); /*
注意: 不要随意使用toArray()
原因: 会把所有的行立即以对象形式组织在内存里.可以在取出少数几行时,用此功能.
*/

【mongoDB中级篇①】游标cursor的更多相关文章

  1. 【mongoDB中级篇②】索引与expain

    索引的操作 数据库百分之八十的工作基本上都是查询,而索引能帮我们更快的查询到想要的数据.但是其降低了数据的写入速度,所以要权衡常用的查询字段,不必在太多字段上建立索引. 在mongoDB中默认是用bt ...

  2. MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划

    这篇文章主要介绍了MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划的相关资料,需要的朋友可以参考下 一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存 ...

  3. MongoDB 索引篇

    MongoDB 索引篇 索引的简介 索引可以加快查询的速度,但是过多的索引或者规范不好的索引也会影响到查询的速度.且添加索引之后的对文档的删除,修改会比以前速度慢.因为在进行修改的时候会对索引进行更新 ...

  4. Prism+MaterialDesign+EntityFramework Core+Postgresql WPF开发总结 之 中级篇

    本着每天记录一点成长一点的原则,打算将目前完成的一个WPF项目相关的技术分享出来,供团队学习与总结. 总共分三个部分: 基础篇主要争对C#初学者,巩固C#常用知识点: 中级篇主要争对WPF布局与Mat ...

  5. Python 正则表达式入门(中级篇)

    Python 正则表达式入门(中级篇) 初级篇链接:http://www.cnblogs.com/chuxiuhong/p/5885073.html 上一篇我们说在这一篇里,我们会介绍子表达式,向前向 ...

  6. SQL Server 数据库的维护(四)__游标(cursor)

    --维护数据库-- --游标(cursor)-- --概述: 注:使用select语句查询结果的结果集是一个整体,如果想每次处理一行或一部分行数据,游标可以提供这种处理机制.可以将游标理解为指针.指针 ...

  7. 25个增强iOS应用程序性能的提示和技巧(中级篇)(3)

    25个增强iOS应用程序性能的提示和技巧(中级篇)(3) 2013-04-16 14:42 破船之家 beyondvincent 字号:T | T 本文收集了25个关于可以提升程序性能的提示和技巧,分 ...

  8. 25个增强iOS应用程序性能的提示和技巧(中级篇)(2)

    25个增强iOS应用程序性能的提示和技巧(中级篇)(2) 2013-04-16 14:42 破船之家 beyondvincent 字号:T | T 本文收集了25个关于可以提升程序性能的提示和技巧,分 ...

  9. 25个增强iOS应用程序性能的提示和技巧--中级篇

    25个增强iOS应用程序性能的提示和技巧--中级篇 标签: ios性能优化内存管理 2013-12-13 10:55 738人阅读 评论(0) 收藏 举报  分类: IPhone开发高级系列(34)  ...

随机推荐

  1. ASP.ENT Core Linux 下 为 donet创建守护进程(转载)

    原文地址:http://www.cnblogs.com/savorboard/p/dotnetcore-supervisor.html 前言 在上篇文章中介绍了如何在 Docker 容器中部署我们的 ...

  2. Delphi XE5教程10:Delphi字符集

    内容源自Delphi XE5 UPDATE 2官方帮助<Delphi Reference>,本人水平有限,欢迎各位高人修正相关错误!也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者可 ...

  3. C程序调用shell脚本共有三种方法

    C程序调用shell脚本共有三种法子 :system().popen().exec系列函数call_exec1.c ,内容为:system() 不用你自己去产生进程,它已经封装了,直接加入自己的命令e ...

  4. SQLserver行转列与列转行

    行表: 行表 姓名 属性 属性值 JACK 身高 180 JACK 体重 80 JACK 年龄 27 TOM 身高 164 TOM 体重 59 TOM 年龄 20 列表: 列表 姓名 身高 年龄 体重 ...

  5. hive 操作(转)

    1.命令行操作 (1)打印查询头,需要显示设置: set hive.cli.print.header=true; (2)加"--",其后的都被认为是注释,但 CLI 不解析注释.带 ...

  6. PDF打印

    问题: Microsoft Excel 不能访问文件“D:\bwms\源代码\Dcjet.BWMS\Dcjet.Bwms.Web\PrintTmp\Check_bwms.xls”. 可能的原因有以下几 ...

  7. 我应该直接学Swift还是Objective-C?

    当我们发布了Swift语言学习课程之后,收到了很多邮件和私信来问自己是否还需要学习C或者Objective-C.此外,人们似乎还在迷惑Swift到底适合iOS开发生态中的哪些部分.通过这篇文章,我希望 ...

  8. 微软职位内部推荐-Software Development Engineer II

    微软近期Open的职位: Job Title:Software Development EngineerII Division: Server & Tools Business - Comme ...

  9. java 词法分析器

    参考:http://www.cnblogs.com/yanlingyin/archive/2012/04/17/2451717.html 实现了一个简单的java词法分析器 功能:词法分析下面一段ja ...

  10. Ubuntu多系统安装注意事项

    1. 安装 选择分区时一定要全设置成逻辑分区,不能是主分区! 2.多系统引导向修复 利用LiveCD制作U盘启动进入Ubuntu系统,若挂载点为: /dev/sda9             swap ...