MongoDB查询与游标之分布式文件存储

目录
  • 一、查询
    • 1、find()基本用法
    • 2、指定要返回的键
    • 3、查询条件
    • 4、or查询
    • 5、$not
  • 二、特定类型的查询
    • 1、null
    • 2、正则表达式
    • 3、查询数组
    • 4、数组与范围查找的相互作用
  • 三、游标
  • 四、游标的生命周期
  • 五、limit、skip、soat
    • 1、常用的查询选项
    • 2、使用skip进行分页
    • 3、不用skip进行分页

一、查询

1、find()基本用法

查询就是返回集合中文档的一个子集,子集的范围从0个文档到整个集合。要返回哪些文档由find的第一个参数决定,该参数是一个用于指定查询条件的文档。

如果是空,则返回全部文档。

当向查询文档中添加键值对时,就意味着限定了查询条件。例如db.users.find({"name":"哪吒编程"})

可以在查询文档时,传入多个键值对,相当于关系型数据库中的where ... and ...

2、指定要返回的键

有时候,只想查询文档中的部分键

> db.users.find({},{"id":1,"dept":1})
{ "_id" : ObjectId("638b2822bb535f1c23f9b09a"), "id" : "1", "dept" : [ { "name" : "哪吒编程", "age" : 18, "address" : "大连" }, { "name" : "云韵", "age" : 19, "address" : "大连" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] }
{ "_id" : ObjectId("638b3944bb535f1c23f9b09b"), "id" : "1", "dept" : [ { "name" : "哪吒编程", "age" : 18, "address" : "大连" }, { "name" : "云韵", "age" : 19, "address" : "大连" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] }

> db.users.find({},{"_id":0,"dept":1})
{ "dept" : [ { "name" : "哪吒编程", "age" : 18, "address" : "大连" }, { "name" : "云韵", "age" : 19, "address" : "大连" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] }
{ "dept" : [ { "name" : "哪吒编程", "age" : 18, "address" : "大连" }, { "name" : "云韵", "age" : 19, "address" : "大连" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] }

3、查询条件

$lt、$lte、$gt、$gte都属于比较运算符,分别对应<、<=、>、>=

可以将其组合使用以查找一个范围内的值。

> db.users.find({"dept.age":{"$gte":20,"$lte":30}})

4、or查询

MongoDB中有两种方式可以进行or查询。$in可以用来查询一个键的多个值。$or则更通用一些,可以在多个键中查询任意的给定值。

> db.users.find({"id":{"$in":["1","3"]}})
{ "_id" : ObjectId("638b2822bb535f1c23f9b09a"), "id" : "1", "dept" : [ { "name" : "哪吒编程", "age" : 18, "address" : "大连" }, { "name" : "云韵", "age" : 19, "address" : "大连" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] }
{ "_id" : ObjectId("638b3944bb535f1c23f9b09b"), "id" : "1", "dept" : [ { "name" : "哪吒编程", "age" : 18, "address" : "大连" }, { "name" : "云韵", "age" : 19, "address" : "大连" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] }
{ "_id" : ObjectId("638b4cacbb535f1c23f9b09c"), "id" : "3", "dept" : [ { "name" : "哪吒编程", "age" : 18, "address" : "大连" }, { "name" : "云韵", "age" : 19, "address" : "大连" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] }
>

5、$not

$not是一个元条件运算符,可以用于任何其它条件之上。

二、特定类型的查询

1、null

null的行为有一些特别。它可以与自身匹配。

> db.users.find({"dept":null})
{ "_id" : ObjectId("638b538682bdbdfa72665a11"), "id" : "1", "dept" : null }

2、正则表达式

"$regex"可以在查询中为字符串的模式匹配提供正则表达式功能。正则表达式对于灵活的字符串匹配非常有用。

> db.users.find({"name":{"$regex":"哪吒"}}))
{ "_id" : ObjectId("638b549982bdbdfa72665a12"), "id" : "1", "name" : "哪吒编程", "age" : 18 }
{ "_id" : ObjectId("638b54cd82bdbdfa72665a15"), "id" : "1", "name" : "CSDN哪吒", "age" : 18 }

MongoDB会使用Perl兼容的正则表达式(PRCE)库来对正则表达式进行匹配。任何PCRE支持的正则表达式语法都能被MongoDB接受。

3、查询数组

$all可以通过多个元素匹配数组。

> db.workers.find({name:{$all:["哪吒编程","云韵"]}})
{ "_id" : ObjectId("638b2154bb535f1c23f9b098"), "id" : "1", "name" : [ "哪吒编程", "云韵" ] }
{ "_id" : ObjectId("638b59fc82bdbdfa72665a16"), "id" : "1", "name" : [ "哪吒编程", "云韵", "美杜莎" ] }
{ "_id" : ObjectId("638b59fc82bdbdfa72665a17"), "id" : "2", "name" : [ "哪吒编程", "云韵", "纳兰嫣然" ] }

如果想在数组中查询特定位置的元素,可以使用key.index语法来指定下标:

> db.workers.find({"name.2":"美杜莎"})
{ "_id" : ObjectId("638b59fc82bdbdfa72665a16"), "id" : "1", "name" : [ "哪吒编程", "云韵", "美杜莎" ] }

通过$size指定要查找的数组的大小:

> db.workers.find({"name":{"$size":2}})
{ "_id" : ObjectId("638b2154bb535f1c23f9b098"), "id" : "1", "name" : [ "哪吒编程", "云韵" ] }

4、数组与范围查找的相互作用

先举一个例子:

> db.student.find()
{ "_id" : ObjectId("638b6b8382bdbdfa72665a19"), "id" : "1", "name" : "哪吒编程", "age" : 18 }
{ "_id" : ObjectId("638b6b8482bdbdfa72665a1a"), "id" : "2", "name" : "云韵", "age" : 23 }
{ "_id" : ObjectId("638b6b8482bdbdfa72665a1b"), "id" : "3", "name" : "美杜莎", "age" : [ 15, 29 ] }
{ "_id" : ObjectId("638b6b8582bdbdfa72665a1c"), "id" : "3", "name" : "萧炎", "age" : 38 }
> db.student.find({"age":{"$gt":20,"$lt":28}})
{ "_id" : ObjectId("638b6b8482bdbdfa72665a1a"), "id" : "2", "name" : "云韵", "age" : 23 }
{ "_id" : ObjectId("638b6b8482bdbdfa72665a1b"), "id" : "3", "name" : "美杜莎", "age" : [ 15, 29 ] }

和想象中的不太一样啊,我的本意是查询年龄在20~28之间的人,为什么呢?

文档中的标量(非数组元素)必须与查询条件中的每一条子句相匹配。如果使用db.student.find({"age":{"$gt":20,"$lt":28}})进行查询,那么age必须介于20~28之间,然而,如果age是一个数组,那么当age键中的某一个元素与查询条件的任意一条语句相匹配时,文档也会被返回。(即15<28,29大于20),完美适配。

这样就会使针对数组的范围查询失去了作用。

此时,可以使用"$elemMatch"强制MongoDB将这两个子句与单个数组元素进行比较。不过,"$elemMatch"不会匹配非数组元素。

-- 返回空
db.student.find({"age":{"$elemMatch":{"$gt":20,"$lt":28}}})

如果在查询的字段上有索引,那么可以使用min和max将查询条件遍历的索引范围限制为"$gt""$lt"的值。

db.student.find({"age":{"$gt":20,"$lt":28}}).min({"age":20}).max({"age":28})

现在,这条查询语句只会遍历值在20~28之间的索引。

三、游标

数据库会使用游标返回find的执行结果。游标的客户端实现通常能够在很大程度上对查询的最终输出进行控制。你可以限制结果的数量,跳过一些结果,按任意方向的任意键组合对结果进行排序,以及执行徐国其他功能强大的操作。

通过cursor.hasNext()检查是否还有其它结果,通过cursor.next()用来对其进行获取。

调用find()时,shell并不会立即查询数据库,而是等到真正开始请求结果时才发送查询,这样可以在执行之前给查询附加额外的选项。cursor对象的大多数方法会返回游标本身,这样就可以按照任意顺序将选项链接起来了。

在使用db.users.find();查询时,实际上查询并没有真正执行,只是在构造查询,执行cursor.hasNext(),查询才会发往服务器端。shell会立刻获取前100个结果或者前4MB的数据(两者之中的较小者),这样下次调用next或者hasNext时就不必再次连接服务器去获取结果了。在客户端遍历完第一组结果后,shell会再次连接数据库,使用getMore请求更多的结果。getMore请求包含一个游标的标识符,它会向数据库询问是否还有更多的结果,如果有则返回下一批结果。这个过程会一直持续,直到游标耗尽或者结果被全部返回。

四、游标的生命周期

在服务器端,游标会占用内存和资源。一旦游标遍历完结果之后,或者客户端发送一条消息要求终止,数据库就可以释放它正在使用的资源。

何时销毁游标:

  1. 当游标遍历完匹配的结果时,它会消除自身;
  2. 当游标超出客户端的作用域时,驱动程序会向数据库发送一条特殊的消息,让数据库终止该游标;
  3. 如果10分钟没有被使用的话,数据库游标也将自动销毁;

五、limit、skip、soat

1、常用的查询选项

最常用的查询选项是限制返回结果的数量、略过一定数量的结果以及排序。所有这些选项必须在查询被发送到数据库之前指定。

  • limit:限制数量;
  • skip:略过;
  • soat:排序,1是升序,-1是降序;

使用skip略过少量的文档是可以的,但对于结果非常多的情况,skip会非常慢,因为要首先找到被略过的结果,然后再丢弃这些数据。

2、使用skip进行分页

最简单的分页方式是

> db.student.find().sort({"id":1}).limit(5)
{ "_id" : ObjectId("638b6b8382bdbdfa72665a19"), "id" : "1", "name" : "哪吒编程", "age" : 18 }
{ "_id" : ObjectId("638c6685e96330d24f819176"), "id" : "1", "name" : "哪吒编程", "age" : 18 }
{ "_id" : ObjectId("638c6685e96330d24f81917f"), "id" : "10", "name" : "云韵", "age" : 23 }
{ "_id" : ObjectId("638c6685e96330d24f819180"), "id" : "11", "name" : "美杜莎", "age" : 29 }
{ "_id" : ObjectId("638c6686e96330d24f819181"), "id" : "12", "name" : "萧炎", "age" : 38 }
> db.student.find().sort({"id":1}).skip(5).limit(5)
{ "_id" : ObjectId("638b6b8482bdbdfa72665a1a"), "id" : "2", "name" : "云韵", "age" : 23 }
{ "_id" : ObjectId("638c6685e96330d24f819177"), "id" : "2", "name" : "云韵", "age" : 23 }
{ "_id" : ObjectId("638b6b8582bdbdfa72665a1c"), "id" : "3", "name" : "萧炎", "age" : 38 }
{ "_id" : ObjectId("638b6b8482bdbdfa72665a1b"), "id" : "3", "name" : "美杜莎", "age" : [ 15, 29 ] }
{ "_id" : ObjectId("638c6685e96330d24f819178"), "id" : "3", "name" : "美杜莎", "age" : 29 }
> db.student.find().sort({"id":1}).skip(10).limit(5)
{ "_id" : ObjectId("638c6685e96330d24f819179"), "id" : "4", "name" : "萧炎", "age" : 38 }
{ "_id" : ObjectId("638c6685e96330d24f81917a"), "id" : "5", "name" : "哪吒编程", "age" : 18 }
{ "_id" : ObjectId("638c6685e96330d24f81917b"), "id" : "6", "name" : "云韵", "age" : 23 }
{ "_id" : ObjectId("638c6685e96330d24f81917c"), "id" : "7", "name" : "美杜莎", "age" : 29 }
{ "_id" : ObjectId("638c6685e96330d24f81917d"), "id" : "8", "name" : "萧炎", "age" : 38 }
>

3、不用skip进行分页

可以通过以下方式:

到此这篇关于MongoDB查询与游标之彻底玩转分布式文件存储的文章就介绍到这了,更多相关MongoDB查询与游标内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MongoDB高可用与分片

    目录 一.复制 二.如何进行选举 三.优先级 四.选举仲裁者 五.同步 六.处理过时数据 七.哈希片键 ​​​​​​八.多热点 九.分片规则 1.分片的限制 2.片键的基数 十.控制数据分发 1.自动分片 2.手动分发 一.复制 在MongoDB中,创建副本集后就可以使用复制功能了,副本集是一组服务器,其中一个用于处理写操作的主节点primary,还有多个用于保存主节点数据副本的从节点secondary.如果主节点崩溃了,则从节点会选取出一个新的主节点. 如果使用复制功能时有一台服务器停止运行了

  • 解决mongo的tickets被耗尽导致卡顿问题

    目录 tickets是什么 思考历程 总结 近一年来,项目线上环境的mongo数据库出现多次tickets被耗尽,导致数据库卡顿,并且都是突然出现,等待一段时间后又能自动恢复. 为了解决这个问题,我们进行了长期的探索和研究,先后从多个角度进行优化,于此记录和分享一下这一路的历程. tickets是什么 为了解决这个问题,我们首先要明白ticktes是什么,其实网上基本都说的一知半解,没有一个能说明白的,但是有一个查询tieckts消耗情况的mongo命令: db.serverStatus().w

  • Mongoose find 查询返回json数据处理方式

    目录 前言 需求 处理思路 遇到问题 解决方案 总结 前言 Mongoose find方法,打印看着返回的是json数据,实际返回的是Mongoose实例,为了方便自定义拓展或操作链式操作. 需求 如图复制按钮,点击复制按钮填写信息,复制出有相同属性的数据模型: 处理思路 传参:{id:"", //被复制的数据模型id ...(其他填写参数) };通过id查询被复制数据模型所有数据,删除数据id,删除属性id,其他填写参数覆盖,然后写库. 遇到问题 代码如下,执行时,直接报堆栈溢出,获

  • SpringBoot 使用Mongo的GridFs实现分布式文件存储操作

    目录 前言 GridFs介绍 什么时候使用GridFs GridFs的原理 环境 引入依赖和项目配置 使用GridFsTemplate操作GridFs 前言 这段时间在公司实习,安排给我一个任务,让在系统里实现一个知识库的模块,产品说,就像百度网盘那样...我tm-,这不就是应了那句话,"这个需求很简单,怎么实现我不管". 可是我google小能手怎么会认输呢,本来还说研究一下FastDFS啥的,但是因为我们项目用的Mongo作为数据库,了解到Mongo自带分布式文件系统GridFs,

  • java操作mongoDB查询的实例详解

    java操作mongo查询的实例详解 前言: MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型.Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且

  • MongoDB快速入门笔记(四)之MongoDB查询文档操作实例代码

    MongoDB简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 下面给大家介绍MongoDB查询文档操作的实例 先把student删除,再重新插入数据 > db.student.drop() true > db.student.insert([{ "_id" : 1, "

  • 利用mongodb查询某坐标是否在规定多边形区域内的方法

    前言 大家都知道MongoDB是一个基于分布式文件存储的数据库,并提供创建基于地理空间的索引的能力,本文将使用MongoDB 基于地理空间索引进行坐标所在区域的判断及使用. 1.使用百度拾取坐标工具,在地图上定义多边形的坐标点,并把每个点的坐标保存. 百度拾取坐标工具:http://api.map.baidu.com/lbsapi/getpoint/ 多边形的坐标点如下: 113.314882,23.163055 113.355845,23.167042 113.370289,23.149564

  • MongoDB 查询操作的实例详解

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

  • PHP基于文件存储实现缓存的方法

    本文实例讲述了PHP基于文件存储实现缓存的方法.分享给大家供大家参考.具体如下: 在一些数据库数据记录较大,但是服务器有限的时候,可能一条MySQL查询就会好几百毫秒,一个简单的页面一般也有十几条查询,这个时候也个页面加载下来基本要好几秒了,如果并发量高的话服务器基本就瘫痪了,造成一个页面很久也加载不下来,这个时候我们可以使用文件缓存来缓解下MySQL的压力,下面给个使用例子. <?php //页面业务逻辑处理,获得结果 $objPage = new Page_IndexModel($arrPa

  • 详解用python实现基本的学生管理系统(文件存储版)(python3)

    这个是升级的版本,比较进阶一点的,相对与之前的文件管理系统,数据只是存储到了内存中,而不是存储到硬盘上,我们想让文件存储到硬盘上的话,一个是存储到文件里,一个是存储到数据库中,存储到数据库中的版本会后续发布,先来看一下文件存储版,是把学生信息存储到了txt文件中,我这里是默认存储到了students.txt文件中,想更改文件名字根据代码修改即可,代码中注释很详细,我也是python初学者,欢迎大家和我交流! """ 学生管理系统(文件存储版) 再原有功能的基础上添加了如下功能

  • EventStore文件存储设计详解

    背景 ENode是一个CQRS+Event Sourcing架构的开发框架,Event Sourcing需要持久化事件,事件可以持久化在DB,但是DB由于面向的是CRUD场景,是针对数据会不断修改或删除的场景,所以内部实现会比较复杂,性能也相对比较低.而Event Store实际上对数据只有新增和查询的需求,所以我想为Event Sourcing的场景针对性的实现一个Event Store.看了一下业界的一些实现,感觉都没有达到我的期望,所以想自己动手实现一个.下面是我构思的一个Event St

  • PHP中如何使用Redis接管文件存储Session详解

    前言 php默认使用文件存储session,如果并发量大,效率会非常低.而redis对高并发的支持非常好,可以利用redis替换文件来存储session. 最近就遇到了这个问题,之前找了网上的一套直播系统给客户用,刚开始是没问题的,在后面人数上来之后网站开始变得卡顿,卡的一批.之后查看php慢日志发现session_start()的身影,好吧,原来是万恶的文件存储session,跟我之前进的坑一模一样--之前做的教务查询系统直接用的session没有用cookie,结果在高并发的情况下php原地

  • FastDFS分布式文件系统环境搭建及安装过程解析

    FastDFS:分布式文件系统 它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题. 特别适合以文件为载体的在线服务,如相册网站.视频网站等等. FastDFS为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标, 使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传.下载等服务. FastDFS服务端有两个角色: 跟踪器(tracker)和存储节点(storage). 跟踪器主要

随机推荐