正文
mongodb更新语法详解,mongodb 更新
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
mongodb之remove操作
在上一篇 mongodb基础操作之update更新操作 中详细介绍了常用的字段更新操作符,本篇开始介绍remove 的api详细操作,mongodb remove api操作分为remove、deleteOne、deleteMany三种。
1. remove
说明:从集合中删除文档。
语法:
db.collection.remove(
,
{
justOne: ,
writeConcern: ,
collation:
}
)
参数讲解:
query:使用查询操作符指定删除条件。要删除集合中的所有文档,传递一个空文档({})。
justOne:可选的。若要仅删除一个文档,请设置为true。省略使用缺省值false并删除所有匹配删除标准的文档。
writeConcern:可选的。表达写作关注的文件。忽略使用默认的写关注点。如果在事务中运行,请不要显式设置操作的写关注。要对事务使用write concern,。
collation:可选的。指定操作要使用的排序规则。
排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号的规则。
排序选项有以下语法:
1.1. 示例
db.articles.remove({"views":{$gt:4}},true)
db.articles.remove({})
2. deleteOne
说明:
从集合中移除单个文档。
语法:
db.collection.deleteOne(
,
{
writeConcern: ,
collation: ,
hint: // 在MongoDB 4.4中可用
}
)
参数讲解:
filter:使用查询操作符指定删除条件。指定一个空文档{}来删除集合中返回的第一个文档。
writeConcern:可选的。表达写作关注的文件。忽略使用默认的写关注点。如果在事务中运行,请不要显式设置操作的写关注。要对事务使用write concern,
collation:可选的。指定操作要使用的排序规则。排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号的规则。
hint:可选的。指定操作要使用的排序规则。排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号的规则。指定用于支持查询谓词的索引的文档或字符串。
2.1. 示例
db.orders.deleteOne( { "_id" : ObjectId("563237a41a4d68582c2509da") } );
3. db.collection.deleteMany()
说明:
从集合中删除与筛选器匹配的所有文档。
语法:
db.collection.deleteMany(
,
{
writeConcern: ,
collation:
}
)
参数讲解:
filter:使用查询操作符指定删除条件。指定一个空文档{}来删除集合中返回的第一个文档。
writeConcern:可选的。表达写作关注的文件。忽略使用默认的写关注点。如果在事务中运行,请不要显式设置操作的写关注。要对事务使用write concern,
collation:可选的。指定操作要使用的排序规则。排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号的规则。
hint:可选的。指定操作要使用的排序规则。排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号的规则。指定用于支持查询谓词的索引的文档或字符串,4.4新版功能。
3.1. 示例
db.students.deleteMany({"_id":{$in:[1,2]}})
4. 小技巧提取ObjectId的时间戳
ObjectId("5fe3082595b782487444fa0f").getTimestamp()
返回结果:
ISODate("2020-12-23T09:04:37Z")
MongoDB是什么,怎么用?看完你就知道了
MongoDB是一款为web应用程序和互联网基础设施设计的数据库管理系统。没错MongoDB就是数据库,是NoSQL类型的数据库。
(1)MongoDB提出的是文档、集合的概念,使用BSON(类JSON)作为其数据模型结构,其结构是面向对象的而不是二维表,存储一个用户在MongoDB中是这样子的。
使用这样的数据模型,使得MongoDB能在生产环境中提供高读写的能力,吞吐量较于mysql等SQL数据库大大增强。
(2)易伸缩,自动故障转移。易伸缩指的是提供了分片能力,能对数据集进行分片,数据的存储压力分摊给多台服务器。自动故障转移是副本集的概念,MongoDB能检测主节点是否存活,当失活时能自动提升从节点为主节点,达到故障转移。
(3)数据模型因为是面向对象的,所以可以表示丰富的、有层级的数据结构,比如博客系统中能把“评论”直接怼到“文章“的文档中,而不必像myqsl一样创建三张表来描述这样的关系。
(1)文档数据类型
SQL类型的数据库是正规化的,可以通过主键或者外键的约束保证数据的完整性与唯一性,所以SQL类型的数据库常用于对数据完整性较高的系统。MongoDB在这一方面是不如SQL类型的数据库,且MongoDB没有固定的Schema,正因为MongoDB少了一些这样的约束条件,可以让数据的存储数据结构更灵活,存储速度更加快。
(2)即时查询能力
MongoDB保留了关系型数据库即时查询的能力,保留了索引(底层是基于B tree)的能力。这一点汲取了关系型数据库的优点,相比于同类型的NoSQL redis 并没有上述的能力。
(3)复制能力
MongoDB自身提供了副本集能将数据分布在多台机器上实现冗余,目的是可以提供自动故障转移、扩展读能力。
(4)速度与持久性
MongoDB的驱动实现一个写入语义 fire and forget ,即通过驱动调用写入时,可以立即得到返回得到成功的结果(即使是报错),这样让写入的速度更加快,当然会有一定的不安全性,完全依赖网络。
MongoDB提供了Journaling日志的概念,实际上像mysql的bin-log日志,当需要插入的时候会先往日志里面写入记录,再完成实际的数据操作,这样如果出现停电,进程突然中断的情况,可以保障数据不会错误,可以通过修复功能读取Journaling日志进行修复。
(5)数据扩展
MongoDB使用分片技术对数据进行扩展,MongoDB能自动分片、自动转移分片里面的数据块,让每一个服务器里面存储的数据都是一样大小。
MongoDB核心服务器主要是通过mongod程序启动的,而且在启动时不需对MongoDB使用的内存进行配置,因为其设计哲学是内存管理最好是交给操作系统,缺少内存配置是MongoDB的设计亮点,另外,还可通过mongos路由服务器使用分片功能。
MongoDB的主要客户端是可以交互的js shell 通过mongo启动,使用js shell能使用js直接与MongoDB进行交流,像使用sql语句查询mysql数据一样使用js语法查询MongoDB的数据,另外还提供了各种语言的驱动包,方便各种语言的接入。
mongodump和mongorestore,备份和恢复数据库的标准工具。输出BSON格式,迁移数据库。
mongoexport和mongoimport,用来导入导出JSON、CSV和TSV数据,数据需要支持多格式时有用。mongoimport还能用与大数据集的初始导入,但是在导入前顺便还要注意一下,为了能充分利用好mongoDB通常需要对数据模型做一些调整。
mongosniff,网络嗅探工具,用来观察发送到数据库的操作。基本就是把网络上传输的BSON转换为易于人们阅读的shell语句。
因此,可以总结得到,MongoDB结合键值存储和关系数据库的最好特性。因为简单,所以数据极快,而且相对容易伸缩还提供复杂查询机制的数据库。MongoDB需要跑在64位的服务器上面,且最好单独部署,因为是数据库,所以也需要对其进行热备、冷备处理。
因为本篇文章不是API手册,所有这里对shell的使用也是基础的介绍什么功能可以用什么语句,主要是为了展示使用MongoDB shell的方便性,如果需要知道具体的MongoDB shell语法可以查阅官方文档。
创建数据库并不是必须的操作,数据库与集合只有在第一次插入文档时才会被创建,与对数据的动态处理方式是一致的。简化并加速开发过程,而且有利于动态分配命名空间。如果担心数据库或集合被意外创建,可以开启严格模式。
以上的命令只是简单实例,假设如果你之前没有学习过任何数据库语法,同时开始学sql查询语法和MongoDB 查询语法,你会发现哪一个更简单呢?如果你使用的是java驱动去操作MongoDB,你会发现任何的查询都像Hibernate提供出来的查询方式一样,只要构建好一个查询条件对象,便能轻松查询(接下来会给出示例),博主之前熟悉ES6,所以入手MongoDB js shell完成没问题,也正因为这样简洁,完善的查询机制,深深的爱上了MongoDB。
使用java驱动链接MongoDB是一件非常简单的事情,简单的引用,简单的做增删改查。在使用完java驱动后我才发现spring 对MongoDB 的封装还不如官方自身提供出来的东西好用,下面简单的展示一下使用。
这里只举例了简单的链接与简单的MongoDB操作,可见其操作的容易性。使用驱动时是基于TCP套接字与MongoDB进行通信的,如果查询结果较多,恰好无法全部放进第一服务器中,将会向服务器发送一个getmore指令获取下一批查询结果。
插入数据到服务器时间,不会等待服务器的响应,驱动会假设写入是成功的,实际是使用客户端生成对象id,但是该行为可以通过配置配置,可以通过安全模式开启,安全模式可以校验服务器端插入的错误。
要清楚了解MongoDB的基本数据单元。在关系型数据库中有带列和行的数据表。而MongoDB数据的基本单元是BSON文档,在键值中有指向不定类型值的键,MongoDB拥有即时查询,但不支持联结操作,简单的键值存储只能根据单个键来获取值,不支持事务,但支持多种原子更新操作。
如读写比是怎样的,需要何种查询,数据是如何更新的,会不会存在什么并发问题,数据结构化的程度是要求高还是低。系统本身的需求决定mysql还是MongoDB。
在关于schema 的设计中要注意一些原则,比如:
数据库是集合的逻辑与物理分组,MongoDB没有提供创建数据库的语法,只有在插入集合时,数据库才开始建立。创建数据库后会在磁盘分配一组数据文件,所有集合、索引和数据库的其他元数据都保存在这些文件中,查阅数据库使用磁盘状态可通过。
集合是结构上或概念上相似得文档的容器,集合的名称可以包含数字、字母或 . 符号,但必须以字母或数字开头,完全。
限定集合名不能超过128个字符,实际上 . 符号在集合中很有用,能提供某种虚拟命名空间,这是一种组织上的原则,和其他集合是一视同仁的。在集合中可以使用。
其次是键值,在MongoDB里面所有的字符串都是UTF-8类型。数字类型包括double、int、long。日期类型都是UTC格式,所以在MongoDB里面看到的时间会比北京时间慢8小时。整个文档大小会限制在16m以内,因为这样可以防止创建难看的数据类型,且小文档可以提升性能,批量插入文档理想数字范围是10~200,大小不能超过16MB。
(1)索引能显著减少获取文档的所需工作量,具体的对比可以通过 .explain()方法进行对比
(2)解析查询时MongoDB通过最优计划选择一个索引进行查询,当没有最适合索引时,会先不同的使用各个索引进行查询,最终选出一个最优索引做查询
(3)如果有一个a-b的复合索引,那么仅针对a的索引是冗余的
(4)复合索引里的键的顺序是很重要的
(1)单键索引
(2)复合索引
(3)唯一性索引
(4)稀疏索引
如索引的字段会出现null的值,或是大量文档都不包含被索引的键。
如果数据集很大时,构建索引将会花费很长的时间,且会影响程序性能,可通过
当使用 mongorestore 时会重新构建索引。当曾经执行过大规模的删除时,可使用
对索引进行压缩,重建。
(1)查阅慢查询日志
(2)分析慢查询
注意新版本的MongoDB 的explain方法是需要参数的,不然只显示普通的信息。
本节同样主要简单呈现MongoDB副本集搭建的简易性,与副本集的强壮性,监控容易性
提供主从复制能力,热备能力,故障转移能力
实际上MongoDB对副本集的操作跟mysql主从操作是差不多的,先看一下mysql的主从数据流动过程
而MongoDB主要依赖的日志文件是oplog
写操作先被记录下来,添加到主节点的oplog里。与此同时,所有从结点复制oplog。首先,查看自己oplog里最后一条的时间戳;其次,查询主节点oplog里所有大于此时间戳的条目;最后,把那些条目添加到自己的oplog里并应用到自己的库里。从节点使用长轮询立即应用来自主结点oplog的新条目。
当遇到以下情况,从节点会停止复制
local数据库保存了所有副本集元素据和oplog日志
可以使用以下命令查看复制情况
每个副本集成员每秒钟ping一次其他所有成员,可以通过rs.status()看到节点上次的心跳检测时间戳和 健康 状况。
这个点没必要过多描述,但是有一个特殊场景,如果从节点和仲裁节点都被杀了,只剩下主节点,他会把自己降级成为从节点。
如果主节点的数据还没有写到从库,那么数据不能算提交,当该主节点变成从节点时,便会触发回滚,那些没写到从库的数据将会被删除,可以通过rollback子目录中的BSON文件恢复回滚的内容。
(1)使用单节点链接
只能链接到主节点,如果链接到从节点的话,会被拒绝写入操作,但是如果没有使用安全模式,因为mongo的fire and forget 特性,会把拒绝写入的异常给吃掉。
(2)使用副本集方式链接
能根据写入的情况自动进行故障转移,但是当副本集进行新的选举时,还是会出现故障,如果不使用安全模式,依旧会出现写不进去,但现实成功的情况。
分片是数据库切分的一个概念实现,这里也是简单总结为什么要使用分片以及分片的原理,操作。
当数据量过大,索引和工作数据集占用的内存就会越来越多,所以需要通过分片负载来解决这个问题
(1)分片组件
(2)分片的核心操作
分片一个集合:分片是根据一个属性的范围进行划分的,MongoDB使用所谓的分片键让每个文档在这些范围里找到自己的位置
块:是位于一个分片中的一段连续的分片键范围,可以理解为若干个块组成分片,分片组成MongoDB的全部数据
(3)拆分与迁移
块的拆分:初始化时只有一个块,达到最大块尺寸64MB或100000个文档就会触发块的拆分。把原来的范围一分为二,这样就有了两个块,每个块都有相同数量的文档。
迁移:当分片中的数据大小不一时会产生迁移的动作,比如分片A的数据比较多,会将分片A里面的一些块转移到分片B里面去。分片集群通过在分片中移动块来实现均衡,是由名为均衡器的软件进程管理的,任务是确保数据在各个分片中保持均匀分布,当集群中拥有块最多的分片与拥有块最少分片的块差大于8时,均衡器就会发起一次均衡处理。
启动两个副本集、三个配置服务器、一个mongos进程
配置分片
(1)分片查询类型
(2)索引
分片集合只允许在_id字段和分片键上添加唯一性索引,其他地方不行,因为这需要在分片间进行通信,实施起来很复杂。
当创建分片时,会根据分片键创建一个索引。
(1)分片键是不可修改的、分片键的选择非常重要
(2)低效的分片键
(3)理想的分片键
(1)部署拓扑
根据不同的数据中心划分
这里写图片描述
(2)最低要求
(3)配置的注意事项
需要估计集群大小,可使用以下命令对现有集合进行分片处理
(4)备份分片集群
备份分片时需要停止均衡器
(1)部署架构
使用64位机器、32位机器会制约mongodb的内存,使其最大值为1.5GB
(2)cpu
mongodb 只有当索引和工作集都可放入内存时,才会遇到CPU瓶颈,CPU在mongodb使用中的作用是用来检索数据,如果看到CPU使用饱和的情况,可以通过查询慢查询日志,排查是不是查询的问题导致的,如果是可以通过添加索引来解决问题
mongodb写入数据时会使用到CPU,但是mongodb写入时间一次只用到一个核,如果有频繁的写入行为,可以通过分片来解决这个问题
(3)内存
大内存是mongodb的保障,如果工作集大小超过内存,将会导致性能下降,因为这将会增加数据加载入内存的动作
(4)硬盘
mongodb默认每60s会与磁盘强制同步一次,称为后台刷新,会产生I/O操作。在重启时mongodb会将磁盘里面的数据加载至内存,高速磁盘将会减少同步的时间
(5)文件系统
使用ext4 和 xfs 文件系统
禁用最后访问时间
(6)文件描述符
linux 默认文件描述符是1024,需要大额度的提升这个额度
(7)时钟
mongodb各个节点服务器之间使用ntp服务器
(1)绑定IP
启动时使用 - -bind_ip 命令
(2)身份验证
启动时使用 - -auth 命令
(3)副本集身份认证
使用keyFile,注意keyFile文件的权限必须是600,不然会启动不起来
(1)拓扑结构
搭建副本集至少需要两个节点,其中仲裁结点不需要有自己的服务器
(2)Journaling日志
写数据时会先写入日志,而此时的数据也不是直接写入硬盘,而是写入内存
但是Journaling日志会消耗内存,所以可以在主库上面关闭,在从库上面启动
可以单独为Journaling日志使用一块固态硬盘
在插入时,可以通过驱动确保Journaling插入后再反馈,但是会非常影响性能。
logpath 选项指定日志存储地址
-vvvvv 选项(v越多,输出越详细)
db.runCommand({logrotare:1}) 开启滚动日志
(1)serverStatus
这里写图片描述
(2)top
(3)db.currentOp()
动态展示mongodb活动数据
占用当前mongodb监听端口往上1000号的端口
(1)mongodump
把数据库内容导出成BSON文件,而mongorestore能读取并还原这些文件
(2)mongorestore
把导出的BSON文件还原到数据库
(3)备份原始数据文件
可以这么做,但是,操作之前需要进行锁库处理 db.runCommand({fsync:1,lock:true})
db.$cmd.sys.unlock.findOne() 请求解锁操作,但是数据库不会立刻解锁,需要使用db.currentOp()验证。
(1)修复
mongd --repair 修复所有数据库
db.runCommand({repairDatabase:1}) 修复单个数据库
修复就是根据Jourling文件读取和重写所有数据文件并重建各个索引
(2)压紧
压紧,会重写数据文件,并重建集合的全部索引,需要停机或者在从库上面运行,如果需要在主库上面运行,需要添加force参数 保证加写锁。
(1)监控磁盘状态
(2)为提升性能检查索引和查询
总的来说,扫描尽可能少的文档。
保证没有冗余的索引,冗余的索引会占用磁盘空间、消耗更多的内存,在每次写入时还需做更多工作
(3)添加内存
dataSize 数据大小 和 indexSize 索引大小,如果两者的和大于内存,那么将会影响性能。
storageSize超过dataSize 数据大小 两倍以上,就会因磁盘碎片而影响性能,需要压缩。
mongodb 请问php中的这句mysql语法,在mongodb中如何写。
查询:
MySQL:
SELECT * FROM user
Mongo:
db.user.find()
MySQL:
SELECT * FROM user WHERE name = 'starlee'
Mongo:
db.user.find({‘name' : 'starlee'})
插入:
MySQL:
INSERT INOT user (`name`, `age`) values ('starlee',25)
Mongo:
db.user.insert({‘name' : 'starlee', ‘age' : 25})
如果你想在MySQL里添加一个字段,你必须:
ALTER TABLE user….
但在MongoDB里你只需要:
db.user.insert({‘name' : 'starlee', ‘age' : 25, ‘email' : 'starlee@starlee.com'})
删除:
MySQL:
DELETE * FROM user
Mongo:
db.user.remove({})
MySQL:
DELETE FROM user WHERE age 30
Mongo:
db.user.remove({‘age' : {$lt : 30}})
$gt : ; $gte : = ; $lt : ; $lte : = ; $ne : !=
更新:
MySQL:
UPDATE user SET `age` = 36 WHERE `name` = 'starlee'
Mongo:
db.user.update({‘name' : 'starlee'}, {$set : {‘age' : 36}})
MySQL:
UPDATE user SET `age` = `age` + 3 WHERE `name` = 'starlee'
Mongo:
db.user.update({‘name' : 'starlee'}, {$inc : {‘age' : 3}})
MySQL:
SELECT COUNT(*) FROM user WHERE `name` = 'starlee'
Mongo:
db.user.find({‘name' : 'starlee'}).count()
MySQL:
SELECT * FROM user limit 10,20
Mongo:
db.user.find().skip(10).limit(20)
MySQL:
SELECT * FROM user WHERE `age` IN (25, 35,45)
Mongo:
db.user.find({‘age' : {$in : [25, 35, 45]}})
MySQL:
SELECT * FROM user ORDER BY age DESC
Mongo:
db.user.find().sort({‘age' : -1})
MySQL:
SELECT DISTINCT(name) FROM user WHERE age 20
Mongo:
db.user.distinct(‘name', {‘age': {$lt : 20}})
MySQL:
SELECT name, sum(marks) FROM user GROUP BY name
Mongo:
db.user.group({
key : {‘name' : true},
cond: {‘name' : ‘foo'},
reduce: function(obj,prev) { prev.msum += obj.marks; },
initial: {msum : 0}
});
MySQL:
SELECT name FROM user WHERE age 20
Mongo:
db.user.find(‘this.age 20′, {name : 1})
发现很多人在搜MongoDB循环插入数据,下面把MongoDB循环插入数据的方法添加在下面:
for(var i=0;i100;i++)db.test.insert({uid:i,uname:'nosqlfan'+i});
上面一次性插入一百条数据,大概结构如下:
{ “_id” : ObjectId(“4c876e519e86023a30dde6b8″), “uid” : 55, “uname” : “nosqlfan55″ }
{ “_id” : ObjectId(“4c876e519e86023a30dde6b9″), “uid” : 56, “uname” : “nosqlfan56″ }
{ “_id” : ObjectId(“4c876e519e86023a30dde6ba”), “uid” : 57, “uname” : “nosqlfan57″ }
{ “_id” : ObjectId(“4c876e519e86023a30dde6bb”), “uid” : 58, “uname” : “nosqlfan58″ }
{ “_id” : ObjectId(“4c876e519e86023a30dde6bc”), “uid” : 59, “uname” : “nosqlfan59″ }
{ “_id” : ObjectId(“4c876e519e86023a30dde6bd”), “uid” : 60, “uname” : “nosqlfan60″ }
简易对照表
SQL Statement Mongo Query Language Statement
CREATE TABLE USERS (a Number, b Number) implicit; can be done explicitly
INSERT INTO USERS VALUES(1,1) db.users.insert({a:1,b:1})
SELECT a,b FROM users db.users.find({}, {a:1,b:1})
SELECT * FROM users db.users.find()
SELECT * FROM users WHERE age=33 db.users.find({age:33})
SELECT a,b FROM users WHERE age=33 db.users.find({age:33}, {a:1,b:1})
SELECT * FROM users WHERE age=33 ORDER BY name db.users.find({age:33}).sort({name:1})
SELECT * FROM users WHERE age33 db.users.find({'age':{$gt:33}})})
SELECT * FROM users WHERE age33 db.users.find({'age':{$lt:33}})})
SELECT * FROM users WHERE name LIKE "%Joe%" db.users.find({name:/Joe/})
SELECT * FROM users WHERE name LIKE "Joe%" db.users.find({name:/^Joe/})
SELECT * FROM users WHERE age33 AND age=40 db.users.find({'age':{$gt:33,$lte:40}})})
SELECT * FROM users ORDER BY name DESC db.users.find().sort({name:-1})
CREATE INDEX myindexname ON users(name) db.users.ensureIndex({name:1})
CREATE INDEX myindexname ON users(name,ts DESC) db.users.ensureIndex({name:1,ts:-1})
SELECT * FROM users WHERE a=1 and b='q' db.users.find({a:1,b:'q'})
SELECT * FROM users LIMIT 10 SKIP 20 db.users.find().limit(10).skip(20)
SELECT * FROM users WHERE a=1 or b=2 db.users.find( { $or : [ { a : 1 } , { b : 2 } ] } )
SELECT * FROM users LIMIT 1 db.users.findOne()
EXPLAIN SELECT * FROM users WHERE z=3 db.users.find({z:3}).explain()
SELECT DISTINCT last_name FROM users db.users.distinct('last_name')
SELECT COUNT(*y) FROM users db.users.count()
SELECT COUNT(*y) FROM users where AGE 30 db.users.find({age: {'$gt': 30}}).count()
SELECT COUNT(AGE) from users db.users.find({age: {'$exists': true}}).count()
UPDATE users SET a=1 WHERE b='q' db.users.update({b:'q'}, {$set:{a:1}}, false, true)
UPDATE users SET a=a+2 WHERE b='q' db.users.update({b:'q'}, {$inc:{a:2}}, false, true)
DELETE FROM users WHERE z="abc" db.users.remove({z:'abc'});
###################################################
一、操作符
操作符相信大家肯定都知道了,就是等于、大于、小于、不等于、大于等于、小于等于,但是在mongodb里不能直接使用这些操作符。在mongodb里的操作符是这样表示的:
(1) $gt (大于)
(2) $lt (小于)
(3) $gte= (大于等于)
(4) $lt= (小于等于)
(5) $ne!= (不等于)
(6) $inin (包含)
(7) $ninnot in (不包含)
(8) $existsexist (字段是否存在)
(9) $inc对一个数字字段field增加value
(10) $set就是相当于sql的set field = value
(11) $unset就是删除字段
(12) $push把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去
(13) $pushAll同$push,只是一次可以追加多个值到一个数组字段内
(14) $addToSet增加一个值到数组内,而且只有当这个值不在数组内才增加。
(15) $pop删除最后一个值:{ $pop : { field : 1 } }删除第一个值:{ $pop : { field : -1 } }注意,只能删除一个值,也就是说只能用1或-1,而不能用2或-2来删除两条。mongodb 1.1及以后的版本才可以用
(16) $pull从数组field内删除一个等于value值
(17) $pullAll同$pull,可以一次删除数组内的多个值
(18) $ 操作符是他自己的意思,代表按条件找出的数组里面某项他自己。这个比较坳口,就不说了。
二、CURD 增、改、读、删
增加
复制代码代码如下:
db.collection-insert({'name' = 'caleng', 'email' = 'admin#admin.com'});
是不是灰常简单呀,对就是这么简单,它没有字段的限制,你可以随意起名,并插入数据
复制代码代码如下:
db.collection.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } ); 只更新了第一条大于1记录
db.collection.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true ); 大于3的记录 全更新了
db.collection.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false ); 大于4的记录 只加进去了第一条
db.collection.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true ); 大于5的记录 全加进去
查询
复制代码代码如下:
db.collection.find(array('name' = 'bailing'), array('email'='email@qq.com'))
db.collection.findOne(array('name' = 'bailing'), array('email''email@qq.com'))
大家可以看到查询我用了两种不同的写法,这是为什么,其实这跟做菜是一样的,放不同的调料,炒出的菜是不同的味道。下面给大家说一下,这两种调料的不同作用。
findOne()只返回一个文档对象,find()返回一个集合列表。
也就是说比如,我们只想查某一条特定数据的详细信息的话,我们就可以用findOne();
如果想查询某一组信息,比如说一个新闻列表的时候,我们就可以作用find();
那么我想大家这时一定会想到我想对这一个列表排序呢,no problem mongodb会为您全心全意服务
复制代码代码如下:
db.collection.find().sort({age:1}); //按照age正序排列
db.collection.find().sort({age:-1}); //按照age倒序排列
db.collection.count(); //得到数据总数
db.collection.limit(1); //取数据的开始位置
db.collection.skip(10); //取数据的结束位置
//这样我们就实现了一个取10条数据,并排序的操作。
删除
删除有两个操作 remove()和drop()
复制代码代码如下:
db.collection.remove({"name",'jerry'}) //删除特定数据
db.collection.drop() //删除集合内的所有数据
distinct操作
复制代码代码如下:
db.user.distinct('name', {'age': {$lt : 20}})
2. 熟悉MongoDB的数据操作语句,类sql
数据库操作语法
mongo --path
db.AddUser(username,password) 添加用户
db.auth(usrename,password) 设置数据库连接验证
db.cloneDataBase(fromhost) 从目标服务器克隆一个数据库
db.commandHelp(name) returns the help for the command
db.copyDatabase(fromdb,todb,fromhost) 复制数据库fromdb---源数据库名称,todb---目标数据库名称,fromhost---源数据库服务器地址
db.createCollection(name,{size:3333,capped:333,max:88888}) 创建一个数据集,相当于一个表
db.currentOp() 取消当前库的当前操作
db.dropDataBase() 删除当前数据库
db.eval(func,args) run code server-side
db.getCollection(cname) 取得一个数据集合,同用法:db['cname'] or db.cname
db.getCollenctionNames() 取得所有数据集合的名称列表
db.getLastError() 返回最后一个错误的提示消息
db.getLastErrorObj() 返回最后一个错误的对象
db.getMongo() 取得当前服务器的连接对象get the server connection object
db.getMondo().setSlaveOk() allow this connection to read from then nonmaster membr of a replica pair
db.getName() 返回当操作数据库的名称
db.getPrevError() 返回上一个错误对象
db.getProfilingLevel() ?什么等级
db.getReplicationInfo() ?什么信息
db.getSisterDB(name) get the db at the same server as this onew
db.killOp() 停止(杀死)在当前库的当前操作
db.printCollectionStats() 返回当前库的数据集状态
db.printReplicationInfo()
db.printSlaveReplicationInfo()
db.printShardingStatus() 返回当前数据库是否为共享数据库
db.removeUser(username) 删除用户
db.repairDatabase() 修复当前数据库
db.resetError()
db.runCommand(cmdObj) run a database command. if cmdObj is a string, turns it into {cmdObj:1}
db.setProfilingLevel(level) 0=off,1=slow,2=all
db.shutdownServer() 关闭当前服务程序
db.version() 返回当前程序的版本信息
数据集(表)操作语法
db.linlin.find({id:10}) 返回linlin数据集ID=10的数据集
db.linlin.find({id:10}).count() 返回linlin数据集ID=10的数据总数
db.linlin.find({id:10}).limit(2) 返回linlin数据集ID=10的数据集从第二条开始的数据集
db.linlin.find({id:10}).skip(8) 返回linlin数据集ID=10的数据集从0到第八条的数据集
db.linlin.find({id:10}).limit(2).skip(8) 返回linlin数据集ID=1=的数据集从第二条到第八条的数据
db.linlin.find({id:10}).sort() 返回linlin数据集ID=10的排序数据集
db.linlin.findOne([query]) 返回符合条件的一条数据
db.linlin.getDB() 返回此数据集所属的数据库名称
db.linlin.getIndexes() 返回些数据集的索引信息
db.linlin.group({key:...,initial:...,reduce:...[,cond:...]})
db.linlin.mapReduce(mayFunction,reduceFunction,optional params)
db.linlin.remove(query) 在数据集中删除一条数据
db.linlin.renameCollection(newName) 重命名些数据集名称
db.linlin.save(obj) 往数据集中插入一条数据
db.linlin.stats() 返回此数据集的状态
db.linlin.storageSize() 返回此数据集的存储大小
db.linlin.totalIndexSize() 返回此数据集的索引文件大小
db.linlin.totalSize() 返回些数据集的总大小
db.linlin.update(query,object[,upsert_bool]) 在此数据集中更新一条数据
db.linlin.validate() 验证此数据集
db.linlin.getShardVersion() 返回数据集共享版本号
MongoDB 5.0新特性概览
MongoDB 5.0标志着一个新的发布周期的到来,以更快地交付新特性给到用户。版本化API与在线重新分片相结合,使用户不必担心未来的数据库升级以及业务变化问题;本地原生时间序列数据平台也使MongoDB能支持更广泛的工作负载和业务场景;新的MongoDB Shell能够提升用户体验等均为MongoDB 5.0的功能。本文主要介绍MongoDB 5.0的新特性。
MongoDB 5.0通过原生支持整个时间序列数据的生命周期(从采集、存储、查询、实时分析和可视化,到在线归档或随着数据老化自动失效),使构建和运行时间序列应用程序的速度更快、成本更低。随着MongoDB 5.0的发布,MongoDB扩展了通用的应用数据平台,使开发能够更容易地处理时间序列数据,进一步扩展其在物联网、金融分析、物流等方面的应用场景。
MongoDB的时间序列集合以高度优化和压缩的格式自动存储时间序列数据,减少了存储大小和I/O,以实现更好的性能和更大的规模。同时也缩短了开发周期,使您能够快速建立一个针对时间序列应用的性能和分析需求而调优的模型。
创建时间序列数据集合的命令示例:
MongoDB可以无缝地调整采集频率,并根据动态生成的时间分区自动处理无序的测量值。最新发布的MongoDB Connector for Apache Kafka实现了在本地支持时间序列,您可以直接从Kafka主题消息中自动创建时间序列集合,使您在收集数据的同时根据需要对数据进行处理和聚合,然后写入到MongoDB的时间序列集合。
时间序列集合自动创建一个按时间排序的数据聚集索引,降低查询数据的延迟。MongoDB查询API还扩展了窗口函数,您可以运行分析性查询(例如移动平均数和累积总和)。在关系型数据库系统中,这些通常被称为SQL分析函数,并支持以行为单位定义的窗口(即三行移动平均线)。MongoDB更进一步,还增加了指数移动平均线、导数和积分等强大的时间序列函数,支持您以时间为单位定义窗口(例如15分钟的移动平均线)。窗口函数可用于查询MongoDB的时间序列和常规集合,为多种应用类型提供了新的分析方式。另外,MongoDB 5.0也提供了新的时间运算符,包括$dateAdd、$dateSubstract、$dateDiff和$dateTrunc,使您可以通过自定义的时间窗口对数据进行汇总和查询。
您可以将MongoDB的时间序列数据与企业的其他数据相结合。时间序列集合可以与同一个数据库中的常规MongoDB集合放在一起,您不必选择一个专门的时间序列数据库(它不能为任何其他类型的应用提供服务),也不需要复杂的集成来混合时间序列和其他数据。MongoDB通过提供一个统一的平台,让您建立高性能和高效的时间序列应用的同时,也为其他用例或工作负载提供支持,从而消除了整合和运行多个不同数据库的成本和复杂性。
从MongoDB 5.0开始, Write Concern 默认级别为majority,仅当写入操作被应用到Primary节点(主节点)且被持久化到大多数副本节点的日志中的时候,才会提交并返回成功,“开箱即用”地提供了更强的数据可靠性保障。
说明 Write Concern 是完全可调的,您可以自定义配置 Write Concern ,以平衡应用程序对数据库性能和数据持久性的要求。
默认情况下,一个客户端连接对应后端MongoDB服务器上的一个线程( net.serviceExecutor 配置为synchronous)。创建、切换和销毁线程都是消耗较大的操作,当连接数过多时,线程会占用MongoDB服务器较多的资源。
连接数较多或创建连接失控的情况称为“连接风暴”,产生该情况的原因可能是多方面的,且经常是在服务已经受到影响的情况下发生。
针对这些情况,MongoDB 5.0采取了以下措施:
以上措施,加上之前版本在mongos查询路由层的改进,进一步提升了MongoDB承受高并发负载的能力。
长时间运行的快照查询(Long-Running Snapshot Queries)增加了应用程序的通用性和弹性。您可以通过该功能运行默认时间为5分钟的查询(或将其调整为自定义持续时间),同时保持与实时事务性数据库一致的快照隔离,也可以在Secondary节点(从节点)上进行快照查询,从而在单个集群中运行不同的工作负载,并将其扩展到不同的分片上。
MongoDB通过底层存储引擎中一个名为Durable history的项目实现了长期运行的快照查询,该项目早在MongoDB 4.4中就已实现。Durable history将存储自查询开始以来所有变化的字段值的快照。通过使用Durable history,查询可以保持快照隔离,即使在数据发生变化的情况下,Durable history也有助于降低存储引擎的缓存压力,使得业务可以在高写入负载的场景下实现更高的查询吞吐量。
为了提供更好的用户体验,MongoDB 5.0从头开始重新设计了MongoDB Shell(mongosh),以提供一个更现代化的命令行体验,以及增强可用性的功能和强大的脚本环境。新版MongoDB Shell已经成为MongoDB平台的默认shell。新版MongoDB Shell引入了语法高亮、智能自动完成、上下文帮助和有用的错误信息,为您创造一个直观、互动的体验。
随着新的PyMongoArrow API的发布,您可以在MongoDB上使用Python运行复杂的分析和机器学习。PyMongoArrow可以快速将简单的MongoDB查询结果转换为流行的数据格式(例如Pandas数据框架和NumPy数组),帮助您简化数据科学工作流程。
Schema验证(模式验证)是对MongoDB进行数据应用管理控制的一种方式。MongoDB 5.0中,模式验证变得更加简单和友好,当操作验证失败时都会产生描述性的错误信息,帮助您了解不符合集合验证器的验证规则的文档及原因,以快速识别和纠正影响验证规则的错误代码。
MongoDB 5.0支持将正在进行中的索引创建任务在节点重新启动后自动会恢复至原来的位置,减少计划中维护动作对业务的影响。例如:重新启动或升级数据库节点时,您不需要担心当前正在进行的大集合索引创建任务失效。
由于MongoDB支持很多版本和平台,每个发布版本都需在20多个MongoDB支持的平台上进行验证,验证工作量大,降低了MongoDB新功能的交付速度,所以从MongoDB 5.0开始,MongoDB发布的版本将分为Marjor Release(大版本)和Rapid Releases(快速发布版本),其中Rapid Releases作为开发版本提供下载和测试体验,但不建议用在生产环境。
怎么使用java操作mongodb更新整个文档
上篇博客介绍了java操作mongoDB进行对文件的处理。现在来介绍一下对文档的处理。和对文件的处理一样,也是通过java驱动中提供的几个类相互作用完成的。这几个类分别是:
DBCollection类:指定数据库中指定集合的实例,提供了增删改查等一系列操作。在关系型数据库中,对数据的增删改查操作是建立在表的基础上的,在mongodb中是建立在集合的基础上进行的。
DBObject接口:DBObject是键值的映射,因此,可以将DBObject的实现类作为查询的返回结果,也可以作为查询条件
DBCursor:游标,返回结果的集合。
下面是部分实例:
[java] view plaincopy
Mongo mongo = new Mongo();
DB db = mongo.getDB("myMongoDB");
DBCollection course = db.getCollection("course");//对myMongoDB数据库中course集合进行操作
//添加操作
//下面分别是创建文档的几种方式:1. .append() 2. .put() 3. 通过map 4. 将json转换成DBObject对象
DBObject english = new BasicDBObject().append("name","english").append("score", 5).append("id",1);
course.insert(english);
DBObject math = new BasicDBObject();
math.put("id", 2);
math.put("name", "math");
math.put("score", 10);
course.insert(math);
MapString,Object map = new HashMapString,Object();
map.put("name","physics" );
map.put("score", 10);
map.put("id", 3);
DBObject physics= new BasicDBObject(map);
course.insert(physics);
String json ="{'name':'chemistry','score':10,'id':4}";
DBObject chemistry =(DBObject)JSON.parse(json);
course.insert(chemistry);
ListDBObject courseList = new ArrayListDBObject();
DBObject chinese = new BasicDBObject().append("name","chinese").append("score", 10).append("id", 5);
DBObject history = new BasicDBObject().append("name", "history").append("score", 10).append("id", 6);
courseList.add(chinese);
courseList.add(history);
course.insert(courseList);
//添加内嵌文档
String json2 =" {'name':'english','score':10,'teacher':[{'name':'柳松','id':'1'},{'name':'柳松松','id':2}]}";
DBObject english2= (DBObject)JSON.parse(json);
course.insert(english2);
ListDBObject list = new ArrayListDBObject();
list.add(new BasicDBObject("name","柳松").append("id",1));
list.add(new BasicDBObject("name","柳松松").append("id",2));
DBObject english3= new BasicDBObject().append("name","english").append("score",10).append("teacher",list);
//查询
//查询所有、查询一个文档、条件查询
DBCursor cur = course.find();
while(cur.hasNext()){
DBObject document = cur.next();
System.out.println(document.get("name"));
}
DBObject document = course.findOne();
String name=(String)document.get("name");
System.out.println(name);
//查询学分=5的
DBObject query1 = new BasicDBObject("score",5);
DBObject query2 = new BasicDBObject("score",new BasicDBObject("$gte",5));
DBCursor cur2 = course.find(query2);
//条件表达式:$ge() $get(=) $lt() $lte(=) $ne() $in $nin $all $exists $or $nor $where $type等等
//查找并修改
DBObject newDocument = course.findAndModify(new BasicDBObject("score",5), new BasicDBObject("score",15));
//更新操作
//q:更新条件 o:更新后的对象
course.update(new BasicDBObject("score",10), new BasicDBObject("test",15));
course.update(new BasicDBObject("score",15), new BasicDBObject("$set",new BasicDBObject("isRequired",true)));
//两个的区别是,第一个更新是将{"test":15}这个文档替换原来的文档,
//第二个更新添加了条件表达式$set,是在原来文档的基础上添加"isRequired"这个键
//条件表达式:$set $unset $push $inc $push $push $addToSet $pull $pullAll $pop等等
//当_id相同时,执行save方法相当于更新操作
course.save(new BasicDBObject("name","math").append("_id", 1));
course.save(new BasicDBObject("name","数学").append("_id", 1));
//删除符合条件的文档
course.remove(new BasicDBObject("score",15));
//删除集合及所有文档
course.drop();span style="font-family:Arial, Helvetica, sans-serif;"span style="white-space: normal;"
/span/span
上面只是介绍了一些简单的操作,具体复杂的查询更新可以根据需求再去查找文档资料。其实,不管操作简单还是复杂,其核心都是对DBObject和DBCollection的操作,主要掌握DBObject如何构造键值对,以及一些条件表达式。
mongodb更新语法详解的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于mongodb 更新、mongodb更新语法详解的信息别忘了在本站进行查找喔。