前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >MongoDB系列一(查询).

MongoDB系列一(查询).

作者头像
JMCui
发布于 2018-03-21 11:10:30
发布于 2018-03-21 11:10:30
3.6K00
代码可运行
举报
文章被收录于专栏:JMCuiJMCui
运行总次数:0
代码可运行

一、简述

    MongoDB中使用find来进行查询。查询就是返回一个集合中文档的子集,子集合的范围从0个文档到整个集合。默认情况下,"_id"这个键总是被返回,即便是没有指定要返回这个键。("_id"是一个集合中每个文档的唯一标识)

    查询的使用上有限制,传递给数据库的查询文档必须是常量。(当然,在你的代码里可以是正常的变量)

    一个键可以有任意多个条件,但是一个键不能对应多个更新修改器。

    条件语句是内层文档的键,而修改器是外层文档的键。

二、使用find或者findOne函数和查询文档对数据库执行查询

1、db.userInfo.find() --查询所有数据,相当于 select * from userInfo

2、db.userInfo.find({age:22}) --查询 age = 22 的记录,相当于 select * from userInfo where age = 22

3、db.userInfo.find({age:22,name:'zhangsan'}) --查询 age = 22 并且name = 'zhangsan' 的记录,相当于  select * from userInfo where age = 22 and name = 'zhangsan'

tips:匹配正则表达式(4、5):

4、db.userInfo.find({name:/mongo/}) --查询 name 中包含 mongo 的数据, 相当于 select * from userInfo where name like '%mongo%'

5、db.userInfo.find({name:/^mongo/}) --查询 name 中以mongo开头的,相当于 select * from userInfo where name like 'mongo%'

6、db.userInfo.findOne() --查询第一条数据,相当于 select top 1 * from userInfo 与 db.userInfo.find().limit(1)

7、db.userInfo.distinct("name") --查询后去掉当前集合中的某列的重复数据,相当于 select distinct name from userInfo

tips:find 查询的第一个大括号表示查询条件,第二个大括号表示要显示的字段(默认全显示 ):

8、db.userInfo.find({},{name:1,age:1}) --查询指定列name、age的数据,相当于 select name,age from userInfo

9、db.userInfo.find({},{name:0}) --不希望结果集中显示 name 这个字段

tips:排序分页

10、db.userInfo.find().sort({age:1}) --按照年龄升序 11、db.userInfo.find().sort({age:-1}) --按照年龄降序

12、db.userInfo.find().limit(5) --查询前5条数据,相当于 select top 5 * from userInfo

13、db.userInfo.find().skip(10) --查询 10条以后的数据 select * from userInfo where id not in (select top 10 * from userInfo)

14、db.userInfo.find().limit(5).skip(0) --可用于分页 limit是pageSize,skip是 第几页*pageSize(从第0页开始)

15、db.userInfo.find({sex:null}) 

-- 特定类型的查询,比如 null 。它确实可以匹配自身,但是它不仅可以匹配这个键为 null 的文档,也能匹配不包含这个键的文档。如果仅想匹配这个键位 null 的文档,需要修改如下:

-- db.userInfo.find({sex:{'$in':[null],'$exists':true}})

三、使用$条件查询实现范围查询、数据集包含查询、不等式查询,以及其他一些查询

1、$lt(小于)、$lte(小于等于)、$ge(大于)、$gte(大于等于)、$ne 不等于

db.userInfo.find({age:{$gt:22}})     --查询age > 22 的记录,相当于 select * from userInfo where age > 22 db.userInfo.find({age:{$lt:22}})     --查询age < 22 的记录,相当于 select * from userInfo where age < 22 db.userInfo.find({age:{$gte:22}})    --查询 age >= 22 的记录,相当于 select * from userInfo where age >= 22 db.userInfo.find({age:{$lte:22}})    --查询 age <= 22 的记录 ,相当于 select * from userInfo where age <= 22 db.userInfo.find({age:{$gte:23,$lte:26}})    --查询 age >= 23 并且 age <=26 的记录 , 相当于 select * from userInfo where age >= 23 and age <=26

db.userInfo.find({age:{$ne:23}})     --查询 age != 23 的记录 , 相当于 select * from userInfo where age != 23

tips:很遗憾,并没有 $eq(等于)这个操作符。

2、元条件句 $and 、$or、$not

元条件句:即可以用在任何其他条件之上 。

$and 总是希望尽可能用最少的条件来限定结果的范围

db.userInfo.find({"$and" : [{x : {"$lt" : 1}}, {x : 4}]})     --会匹配那些"x"字段的值小于等于1并且等于4的文档。虽然这两个条件看起来是矛盾的,但是这是完全有可能的,比如,如果"x"字段的值是这样一个数组{"x" : [0,4]},那么这个文档就与查询条件相匹配。     --查询优化器不会对"$and"进行优化,这与其他操作符不同。如果把上面的查询改成下面这样,效率会更高:db.userInfo.find({x : {"$lt" : 1, "$in" : [4]}})

$or 第一个条件应该尽可能匹配更多的文档,这样才是最为高效的

db.userInfo.find({$or:[{age:22},{age:25}])     --or与查询,相当于select * from userInfo where age = 22 or age = 25

$not 用在其他条件上的取反,虽然是元条件句,但是不能放在外层文档(否则:unknown top level operator: $not),并且后面必须跟正则表达式或者文档(否则:$not needs a regex or a document)。

db.userInfo.find({age:{'$not':{$gt:23}}});     -- 对于 age>23 返回的文档取反集 db.product.find({name:{$not:/ang/}});    -- 对 name 与正则匹配的结果取反集合

3、$in、$nin、$all、$size、$slice 、$elemMatch

$in 可以用来查询一个键的多个值  db.userInfo.find({age : {"$in" : [22, 23, 24]}})     --查询年龄等于22、23、24的文档 $nin$in 相反,用来查询一个键不属于多个值的文档。

$all (匹配数组) db.food.find({fruit : {$all : ["apple", "banana"]}})    -- 查询 fruit 既含有 apple,又含有banana 的文档。    -- 当然,也可以不使用$all 匹配数组,比如 db.food.find({fruit : ["apple", "banana","orange"]}) 但是,这样子只能唯一匹配数组为["apple", "banana","orange"] 的文档,而且查询数组条件还要保证相同的元素顺序。    --可以使用 key.index 查询数组特定位置的元素。db.food.find({"fruit.2" : "peach"})

$size(匹配数组)     --db.food.find({"fruit" : {"$size" : 3}})     --匹配数组长度为3的文档

$slice(匹配数组)   --$slice 用在find的第二个参数,用来查找某个键匹配的数组元素的一个子集。   --使用"$slice"时将返回文档中的所有键。   --db.blog.findOne({},{comments:{"$slice":2}}) 返回 结果文档中comments数组的前两个子集   --db.blog.findOne({},{comments:{"$slice":[23,10]}}) 返回 结果文档中comments数组的 24-33 子集,不够则全返回。   --db.blog.findOne({},{comments:{"$slice":-1}}) 返回 结果文档中comments数组的最后一个子集 

$elemMatch(匹配数组)   --查询匹配有两种。数组匹配和非数组匹配。非数组匹配必须键的值满足每一条查询条件才行。数组匹配只要键的数组元素分别满足查询条件即可。比如:

                         -- $elemMatch 可以让数组的元素分别要满足查询条件,但是 $elemMatch 不会匹配非数组元素!!

                         -- db.test.find({"x" : {"$elemMatch" : {"$gt" : 10, "$lt" : 20}}) 

4、其他 $exists 、$mod

$exists    --查询某个键时候存在   -- db.userInfo.find({sex:{$exists:true}}) 返回键名含有sex的文档   -- db.userInfo.find({sex:{$exists:false}}) 返回键名不含有sex的文档

$mod   --$mod会将查询的值除以第一个给定值,若余数等于第二个给定值则匹配成功   -- db.userInfo.find({id : {"$mod" : [5, 1]}}

四、查询将会返回一个数据库游标,游标只会在你需要时才将需要的文档批量返回 

数据库使用游标返回find的执行结果。客户端对游标的实现通常能够对最终结果进行有效的控制。可以限制结果的数量,略过部分结果,根据任意键按任意顺序的组合对结果进行各种排序,或者是执行其他一些强大的操作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var cursor = db.driverLocation.find();
while (cursor.hasNext()){
     var object = cursor.next();
     print(object.type);
    }

游标类还实现了JavaScript的迭代器接口,所以可以在forEach循环中使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var cursor = db.driverLocation.find();
cursor.forEach(function(x){
    print(x.type);
    });    

    调用find时,shell并不立即查询数据库,而是等待真正开始要求获得结果时才发送查询,这样在执行之前可以给查询附加额外的选项。几乎游标对象的每个方法都返回游标本身,这样就可以按任意顺序组成方法链。例如,下面几种表达是等价的: > var cursor = db.foo.find().sort({"x" : 1}).limit(1).skip(10); > var cursor = db.foo.find().limit(1).sort({"x" : 1}).skip(10); > var cursor = db.foo.find().skip(10).limit(1).sort({"x" : 1});

此时,查询还没有真正执行,所有这些函数都只是构造查询。当执行 cursor.hasNext() 的时候,查询才真正被执行。这时,查询被发往服务器。shell立刻获取前100个结果或者前4 MB数据(两者之中较小者),这样下次调用next或者hasNext时就不必再次连接服务器取结果了。客户端用光了第一组结果,shell会再一次联系数据库,使用getMore请求提取更多的结果。getMore请求包含一个查询标识符,向数据库询问是否还有更多的结果,如果有,则返回下一批结果。这个过程会一直持续到游标耗尽或者结果全部返回。

游标的生命周期:首先,游标完成匹配结果的迭代时,它会清除自身。另外,如果客户端的游标已经不在作用域内了,驱动程序会向服务器发送一条特别的消息,让其销毁游标。最后,即便用户没有迭代完所有结果,并且游标也还在作用域中,如果一个游标在10分钟内没有使用的话,数据库游标也会自动销毁。

五、还有很多针对游标执行的元操作,包括忽略一定数量的结果,或者限定返回结果的数量,以及对结果排序。 

-- MongoDB处理不同类型的数据是有一定顺序的。有时一个键的值可能是多种类型的,例如,整型和布尔型,或者字符串和null。如果对这种混合类型的键排序,其排序顺序是预先定义好的。优先级从小到大,其顺序如下:

1. 最小值; 2. null; 3. 数字(整型、 4. 字符串; 5. 对象/文档; 6. 数组; 7. 二进制数据 8. 对象ID; 9. 布尔型; 10. 日期型; 11. 时间戳; 12. 正则表达式 13. 最大值 。

-- 不用 skip 进行分页

    如前文提到的,一般分页我们用 db.userInfo.find().limit(pageSize).skip(第n页 * pageSize) 来实现。但是我们注意到,如果数据量大的话,我们总是先取出前 n*pageSize 的条数然后再舍弃掉,显得很不合算。为此,《MongoDB权威指南》向我们介绍了一种方式:利用时间进行排序,拿到前一页

的最后时间,取出时间大于上一页最后时间的 pageSize 条记录,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var latest = null;
//显示第一页
var page1 = db.foo.find().sort({"date" : -1}).limit(100)
while (page1.hasNext()) {
latest = page1.next();
display(latest);
}
// 获取下一页
var page2 = db.foo.find({"date" : {"$gt" : latest.date}});
page2.sort({"date" : -1}).limit(100);

 但是,我发现这样写还是会存在很多问题,比如说:

1、跟上一页最后一个文档的时间一样的文档如果有多个呢?那这样不是会导致一些文档被漏掉了吗?

2、上一页、下一页或许可以解决。那么如果用户点击第四页、第五页呢?

-- 获取一致结果

    数据处理通常的做法是先将数据从数据库中取出来,做一些变换以后,再保存回数据库。但是,MongoDB这边有个机制就是,如果拿出来处理的数据处理后导致体积比原先大很多,会导致数据放不回原来的位置,而把这个数据挪至集合的末尾处。从而引发的隐患就是:分页查询到最后一页的时候,又取到了原来的数据。

    应对这个问题的方法就是对查询进行快照(snapshot)。如果使用了这个选项,查询就在"_id"索引上遍历执行,这样可以保证每个文档只被返回一次。

db.foo.find().snapshot()     快照会使查询变慢,所以应该只在必要时使用快照。例如,mongodump默认在快照上使用查询。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-03-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
mongodb基本指令
根据文章内容总结为摘要总结。
用户1141560
2017/12/26
1.6K0
【原创】MongoDB之常见操作命令汇总
mongodb由 C++ 写就,其名字来自humongous这个单词的中间部分,从名字可见其野心所在就是海量数据的处理。关于它的一个最简洁描述为:scalable, high-performance, open source, schema-free, document-oriented database。MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。 安装及使用: 首先在Ubuntu上安装MongoDB
码神联盟
2018/04/02
1.1K0
Linux系统下MongoDB的简单安装与基本操作
Mongo DB ,是目前在 IT 行业非常流行的一种非关系型数据库(NoSql),其灵活的数据存储方式,备受当前 IT 从业人员的青睐。Mongo DB 很好的实现了面向对象的思想(OO 思想),在 Mongo DB 中 每一条记录都是一个 Document 对象。Mongo DB 最大的优势在于所有的数据持久操作都无需开发人员手动编写 SQL 语句,直接调用方法就可以轻松的实现 CRUD 操作。 一、下载 mongodb 前往 mongodb 官网下载页面:https://www.mongodb.org
张戈
2018/03/23
2.2K0
MongoDB常用28条查询语句
默认每页显示20条记录,当显示不下的情况下,可以用it迭代命令查询下一页数据。注意:键入it命令不能带“;”
IT工作者
2022/07/06
1.7K0
Linux下的Mongodb部署应用梳理
一、Mongodb简介  官网地址:http://www.mongodb.org/ MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能 最丰富,最像关系数据库的。它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。它是由C++语言编写的一个基于分布式文件存储的开源数据库系统,它的目的在于为WEB应 用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系型数据
洗尽了浮华
2018/01/22
5.1K0
Linux下的Mongodb部署应用梳理
MongoDB学习笔记
本篇文章介绍学习MongoDB的一些常用命令,希望能帮助大家. 常用操作 Help查看命令提示 db.help(); db.yourColl.help(); db.youColl.find().help(); 切换/创建数据库 use yourDB; 当创建一个集合(table)的时候会自动创建当前数据库 查询所有数据库 show dbs; 删除当前使用数据库 db.dropDatabase(); 从指定主机上克隆数据库 从指定主机上克隆数据库 从指定的机器上复制指定数据库数据到某个数据库 db.copy
ihoey
2018/10/31
4680
MongoDB常用命令大全,概述、备份恢复
还记得MySQL、Redis、PostgreSQL、ClickHouse常用命令及操作吗?如果忘记可以到这里重新温习:MySQL常用命令,Redis常用命令,PostgreSQL常用命令,ClickHouse常用命令,启动、关闭、连接、备份、导入导出。本文重点讲述MongoDB常用命令。
寻求出路的程序媛
2024/07/17
9710
mongodb查询的语法总结
$size是匹配数组内的元素数量的,如有一个对象:{a:[“foo”]},他只有一个元素:
周小董
2019/03/25
1.6K0
MongoDB常用操作
插入多条测试数据 > for(i=1;i<=1000;i++){ ... db.blog.insert({"title":i,"content":"mongodb测试文章。","name":"刘"+i}); ... }
白墨石
2021/01/13
1.1K0
MongoDB权威指南学习笔记(1)--基础知识与对文档的增删改查
使用.来分割不同命名空间的子集合,例如一个博客系统可能包含两个集合,分别时blog.posts和blog.authors。
earthchen
2020/09/24
5.6K0
MongoDB(3): 查询
  2、如果没有显示指定_id字段隐藏,则默认会显示,显示指定隐藏,如:find({},{"_id":0});
py3study
2020/01/09
1.8K0
MongoDB(3): 查询
MongoDB基本概念
Mongo 是 humongous 的中间部分,在英文里是“巨大无比”的意思。所以 MongoDB 可以翻译成“巨大无比的数据库”,更优雅的叫法是“海量数据库”。Mongodb是一款非关系型数据库,说到非关系型数据库,区别于关系型数据库最显著的特征就是没有SQL语句,数据没有固定的数据类型,关系数据库的所使用的SQL语句自从 IBM 发明出来以后,已经有 40 多年的历史了,但是时至今日,开发程序员一般不太喜欢这个东西,因为它的基本理念和程序员编程的想法不一致。后来所谓的 NoSQL 风,指的就是那些不用 SQL 作为查询语言的数据存储系统,而文档数据库 MongoDB 正是 NoSQL 的代表。看一下当下数据库的排名就会发现,目前排在Mongodb数据库前面的无一例外是老牌的关系型数据库,而在NoSQL序列中,Mongodb排名第一,且有上升的趋势。
Java廖志伟
2022/03/07
6.6K0
MongoDB基本概念
Docker 搭建MongoDB环境
我们还可以通过命令,查看日志,来看我们的MongoDB是否启动成功。
雷子
2021/03/15
6880
Docker 搭建MongoDB环境
全面学习MongoDB,在Spring Boot项目中整合 MongoDB
MongoDB 如今是最流行的 NoSQL 数据库,被广泛应用于各行各业中,很多创业公司数据库选型就直接使用了 MongoDB。MongoDB一经推出就受到了广大社区的热爱,可以说是对程序员最友好的一种数据库,下面我们来了解一下它的特性。
架构师精进
2023/03/23
10.7K0
全面学习MongoDB,在Spring Boot项目中整合 MongoDB
mongoDB 文档查询
1、文档查询db.users.find()等价于db.users.find( {} ) 2、基于and运算符的多个组合条件可以省略and运算符的多个组合条件可以省略and,直接将条件组合即可 3、对于$and运算符内的条件,用[]括起来,相当于数组形式 4、对于数组查询,可以使用基于下标的方式精确配置特定的元素值 5、对于内嵌文档,可以使用”文档键.内嵌文档键”方式进行访问 6、对于数组内内嵌文档的方式,可以使用”数组名.下标.内嵌文档键”方式访问 7、对于哪些列名需要显示可以通过{ field1: <0|1>, … }来设定 8、本文参考:https://docs.mongodb.com/manual/tutorial/query-documents/
Leshami
2018/08/13
3.2K0
mongodb的查询语句学习摘要 原
db.users.find({"age" : 27}) select * from users where age = 27
拓荒者
2019/03/11
7860
【翻译】MongoDB指南/CRUD操作(一)
【原文地址】https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档。 CRUD操作包括创建、读取、更新和删除文档。 创建操作 执行创建或者插入操作可向集合中添加文档。如果集合不存在,插入操作会创建此集合。 MongoDB提供下列方法向集合中插入文档: db.collection.insert() db.collection.insertOne()  3.2版本新增 db.collection.insertMany(
甜橙很酸
2018/03/08
5.5K0
【翻译】MongoDB指南/CRUD操作(一)
MongoDB 常用命令
mongodb由C++编写,其名字来自humongous这个单词的中间部分,从名字可见其野心所在就是海量数据的处理。关于它的一个最简洁描述为:scalable, high-performance, open source, schema-free, document-oriented database。MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。
阳光岛主
2019/02/19
2.2K0
mongodb操作(概述以及相关的命令)
http://blog.csdn.net/ljfbest/article/details/11979609
bear_fish
2018/09/20
6170
python操作mongodb数据库
(6) $push: 和 $ pushAll 都是向数组属性添加元素。# 好像两者没啥区别
bear_fish
2018/09/20
1.7K0
相关推荐
mongodb基本指令
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文