查询就是返回集合中文档的一个子集,子集的范围从0个文档到整个集合。要返回哪些文档由find的第一个参数决定,该参数是一个用于指定查询条件的文档。
如果是空,则返回全部文档。
(资料图)
当向查询文档中添加键值对时,就意味着限定了查询条件。例如db.users.find({"name":"哪吒编程"})
可以在查询文档时,传入多个键值对,相当于关系型数据库中的where ... and ...
。
有时候,只想查询文档中的部分键
> 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" : "北京" } ] }
$lt、$lte、$gt、$gte
都属于比较运算符,分别对应<、<=、>、>=
。
可以将其组合使用以查找一个范围内的值。
> db.users.find({"dept.age":{"$gte":20,"$lte":30}})
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" : "北京" } ] } >
$not
是一个元条件运算符,可以用于任何其它条件之上。
null的行为有一些特别。它可以与自身匹配。
> db.users.find({"dept":null}) { "_id" : ObjectId("638b538682bdbdfa72665a11"), "id" : "1", "dept" : null }
"$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接受。
$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" : [ "哪吒编程", "云韵" ] }
先举一个例子:
> 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请求包含一个游标的标识符,它会向数据库询问是否还有更多的结果,如果有则返回下一批结果。这个过程会一直持续,直到游标耗尽或者结果被全部返回。
在服务器端,游标会占用内存和资源。一旦游标遍历完结果之后,或者客户端发送一条消息要求终止,数据库就可以释放它正在使用的资源。
何时销毁游标:
当游标遍历完匹配的结果时,它会消除自身;当游标超出客户端的作用域时,驱动程序会向数据库发送一条特殊的消息,让数据库终止该游标;如果10分钟没有被使用的话,数据库游标也将自动销毁;最常用的查询选项是限制返回结果的数量、略过一定数量的结果以及排序。所有这些选项必须在查询被发送到数据库之前指定。
limit:限制数量;skip:略过;soat:排序,1是升序,-1是降序;使用skip略过少量的文档是可以的,但对于结果非常多的情况,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 } >
可以通过以下方式:
到此这篇关于MongoDB查询与游标之彻底玩转分布式文件存储的文章就介绍到这了,更多相关MongoDB查询与游标内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
上一篇:工程项目述职报告范文(共5篇)
下一篇:最后一页
北京时间4月2日晚,多个产油国突然宣布将实施自愿减产石油计划,持续时间从5月份持续到2023年底。突如其来的联合减产为近来因银行业危机陷入萎
1、多云 22°2、10首献给母亲的歌,满是感动,太好听了!3、内蒙人内蒙事4、No 1《时间都去哪了》5、演唱:
中邮证券04月03日发布研报称,给予海尔智家(600690 SH,最新价:22 34元)增持评级。评级理由主要包括:1)核心品类市占率稳步提升,品类与模式
中新网北京4月3日电(记者陈杭)4月2日是世界孤独症日,孤独症儿童常被称为“星星的孩子”。当晚,国家游泳中心(下称水立方)第十三次为“星星的
近日,大湾区商事登记中国委托公证(香港)信息化平台上线活动在佛山顺德举办。活动宣布,4月1日起,大湾区商事登记中国委托公证(香港)信息化平
X 关闭
X 关闭
国内首个“云保险鱼塘”长啥样?近日,记者实地进行了探访。在广东省肇庆市四会市国斌水产养殖合作社,记者见到了合作社带头人马国斌。刚刚[+更多]
背景介绍作为应用最广泛的包装用品之一,纸箱承担着容装、保护产品、美观的重要责任。其市场需求也随着国内消费、物流运输及出口包装行业的[+更多]
【资料图】ABB高压电机有限公司研发中心作为ABB电机业务全球研发的重要组成部分,从建成伊始起,就始终致力于“在中国,为中国和世界”作为[+更多]
近日,深圳市国家级专精特新"小巨人"企业名单公布,正弦电气成功入选国家级专精特新"小巨人"企业名单。S I N E E专精特新“小巨人”专[+更多]