MongoDB之查询操作

一、find简介

1、查询所有
>db.test.find()
>db.test.find({})
2、根据键值对
>db.test.find({“key”:value})
3、根据多个键查询,且关系为AND[且的关系]
>db.test.find({“key”:value,“key1”:value1})
4、指定返回的键
>db.test.find({},{“key”:value})
其中value为0代表不返回,value为1代表字段会返回
5、查询限制
传递给数据库的查询文档的值必须是常量。不能是变量,如以下实例即为错误的:
>db.test.find({“key”:“this.key1”})

二、查询条件

1、 比较运算符
“$lt”、“$lte”、“$gt” 和 “$gte” 都属于比较运算符,分别对应<、<=、> 和 >=。
1.1、要查询 18 到 30 岁的用户
>db.test.find({“age”: { “$gte”:18,“$lt”:30 } })
1.2、要查找在 2022 年 1月 1 日前注册的用户
>startTime=new Date(“01/01/2022”)
>db.test.find({“createTime”: {“$lt”:startTime}})
1.3、$ne 文档键值不等于某个特定值
>db.test.find({“name”:{“$ne”:“zhangsan”}})
2、OR查询
MongoDB 中有两种方式可以进行 OR 查询。“ i n " 可 以 用 来 查 询 一 个 键 的 多 个 值 。 " in" 可以用来查询一个键的多个值。" in""or” 则更通用一些,可以在多个键中查询任意的给定值。
>db.test.find({“id”:{“$in”:[1,2,3,4]}})
>db.test.find({“id”:{“$nin”:[1,4]}})
>db.test.find({“$or”:[{“id”:1},{“name”:“zhangsan”}}]})
>db.test.find({“$or”:[{“id”:{“$in”:[1,4]}},{“name”:“zhangsan”}}]})
3、“$not” 是一个元条件运算符:可以用于任何其他条件之上。
如查询会返回 “id” 为 1、6、11、16 等值的数据
>db.test.find({“id”:{“$mod”:[5,1]}})
>db.test.find({“id”:{“$not”:{“$mod”:[5,1]}}})

特定类型的查询

1、null
假设test集合中没有age字段,相当于查询所有
>db.test.find({“age”:null})
2、如果仅想匹配键值为 null 的文档,则需要检查该键的值是否为null,并且通过 “$exists” 条件确认该键已存在。
>db.test.find({“name”:{“$eq”:null,“$exists”:true}})
3、正则表达式
“$regex” 可以在查询中为字符串的模式匹配提供正则表达式功能。
如果要查找所有用户名为 Zhang或 zhang 的用户,那么可以使用正则表达式进行不区分大小写的匹配:
>db.test.find({“name”:{“$regex”:/zhang/i}})
希望匹配如“zhangs”这样的键,那么可以改进一下刚刚的正则表达式
>db.test.find({“name”:{“$regex”:/zhangs?/i}})
注: MongoDB 可以利用索引来查询前缀正则表达式(如/^zhang/)。索引不能用于不区分大小写的搜索(/^zhangs/i)。当正则表达式以插入符号(^)或左锚点(\A)开头时,它就是“前缀表达式”。如果正则表达式使用了区分大小写的查询,那么当字段存在索引时,则可以对索引中的值进行匹配。如果它也是一个前缀表达式,那么可以将搜索限制在由该索引的前缀所形成的范围内的值。

正则表达式也可以匹配自身。虽然很少有人会将正则表达式插入数据库中,但是如果你这么做了,那么它也可以匹配到自身。
>db.test.insert({“name”:/zhang/})
>db.test.find({“name”:/zhang/})
4、数组查询
1)、匹配文档
>db.test.insertOne({“address”:[“addr1”,“addr2”,“addr3”]})
>db.test.find({“address”:“addr1”})
2)、同时包含,且跟顺序无关
>db.test.find({“address”:{“$all”:[“addr1”,“addr2”]}})
3)、精确匹配且顺序必须一致
>db.test.find({“address”:[“addr1”,“addr3”]})
4)、根据下标查询,数组下标都是从0开始
>db.test.find({“address.2”:“addr2”})
5)、查询特定长度的数组
>db.test.find({“address”:{“$size”:3}})
“$size” 并不能与另一个$ 条件运算符(如 “$gt”)组合使用,但这种查询可以通过在文档中添加一个 “size” 键的方式来实现。
>db.test.update(query,{“$push”:{“$address”:“addr3”},{“$inc”:{“size”:1}}})
后续查询就可以通过size来查询,如:
>db.test.find({“size”:{“$gt”:3}})
6)、“$slice” 运算符可以返回一个数组键中元素的子集。
如,返回前10条数据:
>db.test.find(query,{“address”:{“$slice”:10}})
返回后10条记录:
>db.test.find(query,{“address”:{“$slice”:-10}})
指定偏移量和返回的元素数量来获取数组中间的结果:
>db.test.find(query,{“address”:{“$slice”:[23,10]}})
这个操作会略过前 23 个元素,返回第 24~33 个元素。如果数组中的元素少于 33 个,则会返回尽可能多的元素。
7)、返回与查询条件匹配的任意数组元素,使用 $运算符来返回匹配的元素
db.test.find({“name”:“zhangsan”},{“address.$”:1})
这种方式只会返回每个文档中第一个匹配的元素:如果zhangsan 在资料中留下了多地址,那么只有 “comments” 数组中的第一个会被返回。
8)、数组与范围查询的相互作用
比如目前有如下文档
{“x”:5}
{“x”:15}
{“x”:25}
{“x”:[5,25]}
>db.test.find({“x”:{“$gt”:10,“$lt”:20}})
{“x”:15}
>db.test.find({“x”:{“$gt”:10,“$”:25}})
{“x”:15}
{“x”:[5,25]}
5 和 25 都不在 10 和 20 之间,但由于 25 与查询条件中的第一个子句(“x” 的值大于 10)相匹配,5 与查询条件中的第二个子句(“x” 的值小于 20)相匹配,因此这个文档会被返回。
明显与预期结果不一致,所以可以使用 “$elemMatch” 强制 MongoDB 将这两个子句与单个数组元素进行比较。不过,这里有一个问题,“$elemMatch” 不会匹配非数组元素:
>db.test.find({“x”:{“$elemMatch”:{“$gt”:10,“$lt”:20}}})
此时是没有结果返回的
9)、如果在要查询的字段上有索引,那么可以使用min 和 max 将查询条件遍历的索引范围限制为 “$gt” 和 “$lt"的值:
>db.test.find({“x”:{”$gt":10,“$lt”:20}}).min({“x”:10}).max({“x”:20})
现在,这条查询语句只会遍历值在 10 和 20 之间的索引,不会与值为 5 和 25 的这两个条目进行比较。但是,只有在要查询的字段上存在索引时,才能使用 min 和 max,并且必须将索引的所有字段传递给 min 和 max。
在查询可能包含数组的文档的范围时,使用 min 和 max 通常是一个好主意。在整个索引范围内对数组使用 “$gt”/“$lt” 进行查询是非常低效的。它基本上接受任何值,因此会搜索每个索引项,而不仅仅是索引范围内的值。
5、查询内嵌文档
查询姓名为zhang san的人,精确匹配
>db.test.find(“name”:{“first”:“zhang”,“last”:“san”})
针对特定的键进行查询
>db.test.find({“name.first”:“zhang”})
这种点表示法是查询文档和其他文档类型的主要区别。查询文档可以包含点,表示“进入内嵌文档内部”的意思。点表示法也是待插入文档不能包含 . 字符的原因。当试图将 URL 保存为键时,常常会遇到这种限制。解决这个问题的一种方法是在插入前或者提取后始终执行全局替换,用点字符替换 URL 中不合法的字符。
6、内嵌文档中的数组查询
userInfos是一个数组,包含多个userinfo
>db.test.find({“userinfos”:{“$elemMatch”:{“name”:“zhangsan”,“age”:{“$gte”:6}}}})
要正确指定一组条件而无须指定每个键,请使用"$elemMatch",“$elemMatch” 允许你将限定条件进行“分组”。仅当需要对一个内嵌文档的多个键进行操作时才会用到它。

$where查询

键–值对是一种相当有表现力的查询方式,但有些查询依然无法表示。对于无法以其他方式执行的查询,可以使用 “$where” 子句,它允许你在查询中执行任意的 JavaScript 代码。这样就能在查询中做大部分事情了。为安全起见,应该严格限制或消除"$where" 子句的使用。应该禁止终端用户随意使用 “$where"子句。
使用 “$where” 最常见的情况是比较文档中两个键的值。假设有如下文档:
>db.test.insertOne({“name”:“zhangsan”,“age”:10})
>db.test.insertOne({“name”:“lisi”,“age”:20,“height”:20})
返回任意两个字段相等的文档
>db.test.find({”$where":function(){
for(var current in this){
for(var other in this){
if(current!=other&&this[current]==this[other]){
return true;
}
}
}
return false;
}})
如果函数返回 true,文档就作为结果集的一部分返回;如果函数返回 false,文档就不返回。
除非绝对必要,否则不应该使用 “$where” 查询:它们比常规查询慢得多。每个文档都必须从 BSON 转换为 JavaScript 对象,然后通过 “$where” 表达式运行。此外,“$where” 也无法使用索引。因此,只有在没有使用其他方法进行查询时,才可以使用 “$where”。可以先使用其他查询进行过滤,然后再使用"$where" 子句,这样组合使用可以降低性能损失。如果可能,应该使用索引来基于非 $where 子句进行过滤,而 "$where"表达式仅用于对结果进行进一步微调。MongoDB 3.6 增加了$expr 运算符,它允许在 MongoDB 查询语句中使用聚合表达式。因为它不需要执行 JavaScript,所以速度比 $where 快,建议尽可能使用此运算符作为替代。
进行复杂查询的另一种方法是使用聚合工具.

游标

1、数据库会使用游标返回 find 的执行结果。游标的客户端实现通常能够在很大程度上对查询的最终输出进行控制。你可以限制结果的数量,跳过一些结果,按任意方向的任意键组合对结果进行排序,以及执行许多其他功能强大的操作。
>var cursor = db.test.find();
>while(cursor.hasNext()){
obj = cursor.next();
//执行业务逻辑
}
还可以迭代游标
>cursor.forEach(function(x){
print(x.name);
})
调用 find 时,shell 并不会立即查询数据库,而是等到真正开始请求结果时才发送查询,这样可以在执行之前给查询附加额外的选项。cursor 对象的大多数方法会返回游标本身,这样就可以按照任意顺序将选项链接起来了。
var cursor = db.test.find();只是构造查询,查询还没有真正执行,cursor.hasNext()调用时才会执行,这时,查询会被发往服务器端。shell 会立刻获取前 100 个结果或者前 4MB 的数据(两者之中较小者),这样下次调用 next或者 hasNext 时就不必再次连接服务器端去获取结果了。在客户端遍历完第一组结果后,shell 会再次连接数据库,使用getMore 请求更多的结果。getMore 请求包含一个游标的标识符,它会向数据库询问是否还有更多的结果,如果有则返回下一批结果。这个过程会一直持续,直到游标耗尽或者结果被全部返回。
2、limit、skip和sort
只返回 3 个结果
>db.test.find().limit(3)
略过前 3 个匹配的文档
>db.test.find().skip(3)
sort排序方向可以是 1(升序)或 -1(降序)
>db.test.find().sort({“name”:1,“age”:-1})
3、比较顺序
MongoDB 对于类型的比较有一个层次结构。有时一个键的值可能有多种类型:整型和布尔型,或者字符串和 null。如果对混合类型的键进行排序,那么会有一个预定义的排序顺序。从最小值到最大值,顺序如下。
最小值
null
数字(整型、长整型、双精度浮点型、小数型)
字符串
对象/文档
数组
二进制数据
对象 ID
布尔型
日期
时间戳
正则表达式
最大值
4、避免略过大量结果
使用 skip 来略过少量的文档是可以的。但对于结果非常多的情况,skip 会非常慢,因为需要先找到被略过的结果,然后再丢弃这些数据。大多数数据库会在索引中保存更多的元数据以处理 skip,但 MongoDB 目前还不支持这样做,所以应该避免略过大量的数据。通常下一次查询的条件可以基于上一次查询的结果计算出来。
不使用skip对结果进行分页
>var page=db.test.find().sort({“date”:-1}).limit(100)
然后,假设日期是唯一的,可以使用最后一个文档的 “date” 值作为获取下一页的查询条件:
var latest = null;
//显示第一页
while(page.hasNext()){
latest = page.next();
display(latest);
}
//获取第二页
var page2 = db.test.find({“date”:{“$lt”:latest.date}})
page2.sort({“date”:-1}).limit(100)
5、查找一个随机文档
如果是以下方式,有可能会略过很多文档,性能不佳
>db.test.find().skip(random).limit(1)
所以需要一些提前规划,但如果你知道要在集合中查找随机元素,那么有一种高效得多的方法可以执行此操作。诀窍就是在插入文档时为每个文档添加一个额外的随机键。如果正在使用shell,那么可以使用 Math.random() 函数(这会产生 0 和 1 之间的一个随机数):
>random=Math.random();
>db.test.insertOne({“name”:“zhang”,“random”:Math.random()})
>db.test.find({“random”:{“$gt”:random}})
6、游标生命周期
游标包括两个部分:面向客户端的游标和由客户端游标所表示的数据库游标。我们用的基本都是客户端游标:
1)、在服务器端,游标会占用内存和资源。一旦游标遍历完结果之后,或者客户端发送一条消息要求终止,数据库就可以释放它正在使用的资源。释放这些资源可以让数据库将其用于其他用途,这是非常有益的,因此要确保可以尽快(在合理的范围内)释放游标。
2)、还有一些情况可能导致游标终止以及随后的清理。首先,当游标遍历完匹配的结果时,它会清除自身。其次,当游标超出客户端的作用域时,驱动程序会向数据库发送一条特殊的消息,让数据库知道它可以“杀死”该游标。最后,即使用户没有遍历完所有结果而且游标仍在作用域内,如果 10 分钟没有被使用的话,数据库游标也将自动“销毁”。这样,如果客户端崩溃或者出错,MongoDB 就不需要维护上千个被打开的游标了。
3)、这种“超时销毁”的机制通常是用户所期望的:很少有用户愿意花几分钟坐在那里等待结果。然而,有时可能的确需要一个游标维持很长时间。在这种情况下,许多驱动程序实现了一个称为 immortal 的函数,或者类似的机制,它告诉数据库不要让游标超时。如果关闭了游标超时,则必须遍历完所有结果或主动将其销毁以确保游标被关闭。否则,它会一直占用数据库的资源,直到服务器重新启动。

原文地址:https://blog.csdn.net/ntzzzsj

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读552次。com.mongodb.MongoQueryException: Query failed with error code 292 and error message 'Executor error during find command :: caused by :: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting.' on server 11.51.141.63:27017 _mongodb 大文件 下载失败
文章浏览阅读635次,点赞9次,收藏8次。MongoDB 是一种 NoSQL 数据库,它将每个数据存储为一个文档,这里的文档类似于 JSON/BSON 对象,具体数据结构由键值(key/value)对组成。
文章浏览阅读2.1k次。和。_mongodb 日期类型
文章浏览阅读1.7k次。Scalestack等客户期待使用MongoDB Atlas Vector Search和Amazon Bedrock构建下一代应用程序
文章浏览阅读970次。SpringBoot整合中间件mongodb、ES_springboot3 elasticsearch json数据
文章浏览阅读673次。MongoDB 简介_尚医通sql
文章浏览阅读1k次,点赞8次,收藏9次。官网下载MongoDB安装包后进行解压(因了解并不深入,故暂不进行详细说明,自行查找其他安装方法,后期了解深入后将进行该教程的完善)在bin目录下使用命令启动:./mongod --config …/mongodb.conf。该文章任然处于完善中,如果存在错误遗漏的地方,欢迎私信联系。安装相关的nuget包后即可通过以下方法连接数据。YX9010_0@的第二十篇文章。
文章浏览阅读1.2k次,点赞17次,收藏26次。社交场景, 使用 MongoDB 存储存储用户信息, 以及用户发表的朋友圈信息, 通过地理位置索引实现附近的人, 地点等功能.游戏场景, 使用 MongoDB 存储游戏用户信息, 用户的装备, 积分等直接以内嵌文档的形式存储, 方便查询, 高效率存储和访问.物流场景, 使用 MongoDB 存储订单信息, 订单状态在运送过程中会不断更新, 以 MongoDB 内嵌数组的形式来存储, 一次查询就能将订单所有的变更读取出来.物联网场景, 使用 MongoDB 存储所有接入的智能设备信息, 以及设备汇报的日
文章浏览阅读686次。您可以使用 update_one() 方法来更新 MongoDB 中调用的记录或文档。update_one() 方法的第一个参数是 query 对象,用于定义要更新的文档。注释:如果查询找到多个记录,则仅更新第一个匹配项。第二个参数是定义文档新值的对象。_python 更新 mongodb 数据
文章浏览阅读1.3k次。首先来学习一下nosql这里安装就不进行介绍 只记录一下让自己了解mongodb。_nosql注入
文章浏览阅读4.1k次,点赞8次,收藏7次。在data的目录下,创建一个db文件。因为启动MongoDB服务之前必须创建数据库文件的存放文件夹,否则命令不会自动创建,而且不能启动成功。第一步:安装时,Custom是指可以自定义安装路径,然后傻瓜式安装即可(注意:先不要安装图形化工具,否则安装时间会特别长):如果要想连接成功,必须要开服务,即mongod -dbpath C:MongoDBdatadb的cmd要一直开着。然后回车,ctrl+F输入port找到端口号,一般为:27017。打开命令行,然后找到bin文件地址,并输入。_mongodb windows安装
文章浏览阅读5.1k次,点赞3次,收藏43次。详细介绍MongoDB数据库的基本知识,安装方法,基本操作,_mongodb数据库
文章浏览阅读3.2k次。安装教程翻看以往文章。_navicat 连接mongodb
文章浏览阅读426次,点赞9次,收藏12次。win10开放端口:https://blog.csdn.net/m0_43605481/article/details/119255256。我的是阿里云服务器,所以直接在安全组中加入规则,端口范围:27017,授权对象:0.0.0.0。windows在mongodb安装文件夹的bin文件夹中的mongod.cfg。数据库名字是test,打算创建一个用户,账号aaa,密码bbb,权限readWrite。因为该用户是创建在test数据库的,所以在最后要加上test。O了,然后恢复了test的数据。
文章浏览阅读1.1k次。聚合操作主要用于处理数据并返回计算结果。聚合操作将来自多个文档的值组合在一起,按条件分组后,再进行一系列操作(如求和、平均值、最大值、最小值)以返回单个结果。MongoDB的聚合查询​聚合是MongoDB的高级查询语言,它允许我们通过转化合并由多个文档的数据来生成新的在单个文档里不存在的文档信息。MongoDB中聚合(aggregate)主要用于处理数据(例如分组统计平均值、求和、最大值等),并返回计算后的数据结果,有点类似sql语句中的count(*)、groupby。..._如何将几个db的数据统整在一起做查询
文章浏览阅读680次,点赞7次,收藏8次。(2)application.properties配置文件。(4)UserService类。(5)测试和测试结果。
文章浏览阅读1k次,点赞17次,收藏25次。Studio 3T 2023.9 (macOS, Linux, Windows) - MongoDB 的专业 GUI、IDE 和 客户端,支持自然语言查询_mongodb客户端
文章浏览阅读1.1k次,点赞32次,收藏27次。插件式的存储引擎架构可以实现 Server 层和存储引擎层的解耦,可以支持多种存储引擎,如 MySQL 既可以支持 B-Tree 结构的 InnoDB 存储引擎,还可以支持 LSM 结构的 RocksDB 存储引擎。MongoDB 中的记录就是一个 BSON 文档,它是由键值对组成的数据结构,类似于 JSON 对象,是 MongoDB 中的基本数据单元。的简称,是 JSON 文档的二进制表示,支持将文档和数组嵌入到其他文档和数组中,还包含允许表示不属于 JSON 规范的数据类型的扩展。
文章浏览阅读5.1k次,点赞6次,收藏96次。本文设计了一种基于智能室内温度控制的自动调速风扇。以STM32系列单片机为核心主控板,通过程序代码驱动和使用温度传感器模块实现对环境温度的实时监测,并可以实时显示环境温度。同时,可以设置温度检测的上下警告值,根据需求自行调节。_stm32 温控风扇
文章浏览阅读898次,点赞13次,收藏21次。在MongoDB中,我们使用find()和find_one()方法来在集合中查找数据,就像在MySQL数据库中使用SELECT语句来在表中查找数据一样。_pymongo find_one