MongoDB快速实战与基本原理

MongoDB 介绍

什么是 MongoDB

MongoDB 是一个文档数据库(以 JSON 为数据模型),由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
文档来自于“JSON Document”,并非我们一般理解的 PDF、WORD 文档。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,数据格式是 BSON,一种类似 JSON 的二进制形式的存储格式,简称 Binary JSON,和 JSON 一样支持内嵌的文档对象和数组对象,因此可以存储比较复杂的数据类型。Mongo 最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。原则上 Oracle 和 MySQL 能做的事情,MongoDB 都能做(包括 ACID 事务)。
MongoDB 在数据库总排名第 5,仅次于 Oracle、MySQL 等 RDBMS,在 NoSQL 数据库排名首位。从诞生以来,其项目应用广度、社区活跃指数持续上升。

数据库排名网站:https://db-engines.com/en/ranking

image.png

MongoDB6.0 新特性

该版本的主要功能特性包括:

  • 时序集合增强
  • Change Stream 增强
  • 可查询加密
  • 聚合&query 能力增强
  • 集群同步

官网关于升级到 MongoDB6.0 的原因:https://www.mongodb.com/blog/post/big-reasons-upgrade-mongodb-6-0
官方文档:https://www.mongodb.com/docs/v6.0/
MongoDB6.0 发行版本说明:https://www.mongodb.com/docs/v6.0/release-notes/6.0/
阿里云关于 MongoDB6.0 新特性说明:https://help.aliyun.com/document_detail/462614.html?spm=a2c4g.312011.0.0.75b42ab8s9NasS#section-hvy-d22-stk

MongoDB vs 关系型数据库

MongoDB 概念与关系型数据库(RDBMS)非常类似:

SQL 概念MongoDB 概念
数据库(database)数据库(database)
表(table)集合(collection)
行(row)文档(document)
列(column)字段(field)
索引(index)索引(index)
主键(primary key)_id(字段)
视图(view)视图(view)
表连接(table joins)聚合操作($lookup)
  • 数据库(database):最外层的概念,可以理解为逻辑上的名称空间,一个数据库包含多个不同名称的集合。
  • 集合(collection):相当于SQL中的表,一个集合可以存放多个不同的文档。
  • 文档(document):一个文档相当于数据表中的一行,由多个不同的字段组成。
  • 字段(field):文档中的一个属性,等同于列(column)。
  • 索引(index):独立的检索式数据结构,与 SQL 概念一致。
  • _id:每个文档中都拥有一个唯一的 _id 字段,相当于 SQL 中的主键(primary key)。
  • 视图(view):可以看作一种虚拟的(非真实存在的)集合,与 SQL 中的视图类似。从 MongoDB3.4 版本开始提供了视图功能,其通过聚合管道技术实现。
  • 聚合操作($lookup):MongoDB 用于实现“类似”表连接(tablejoin)的聚合操作符。

尽管这些概念大多与 SQL 标准定义类似,但 MongoDB 与传统 RDBMS 仍然存在不少差异,包括:

  • 半结构化

在一个集合中,文档所拥有的字段并不需要是相同的,而且也不需要对所用的字段进行声明。因此,MongoDB 具有很明显的半结构化特点。除了松散的表结构,文档还可以支持多级的嵌套、数组等灵活的数据类型,非常契合面向对象的编程模型。

  • 弱关系

MongoDB 没有外键的约束,也没有非常强大的表连接能力。类似的功能需要使用聚合管道技术来弥补。

MongoDB 技术优势

MongoDB 基于灵活的 JSON 文档模型,非常适合敏捷式的快速开发。与此同时,其与生俱来的高可用、高水平扩展能力使得它在处理海量、高并发的数据应用时颇具优势。

  • JSON 结构和对象模型接近,开发代码量低
  • JSON 的动态模型意味着更容易响应新的业务需求
  • 复制集提供 99.999% 高可用
  • 分片架构支持海量数据和无缝扩容

MongoDB 与关系型数据库对比:


MongoDB关系型数据库
亿级以上数据量轻松支持分库分表
灵活表结构轻松支持Entity Key/Value 表,关联查询比较痛苦
高并发读轻松支持需要优化
高并发写轻松支持需要优化
跨地区集群轻松支持需要定制方案
分片集群轻松支持需要中间件
地理位置查询比较完整的地理位置PG 还可以,其他数据库略麻烦
聚合计算功能很强大使用 Group By 等,能力有限
异构数据轻松支持使用 EKV 属性表
大宽表轻松支持性能受限

MongoDB 应用场景

从目前阿里云 MongoDB 云数据库上的用户看,MongoDB 的应用已经渗透到各个领域:

  • 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新;
  • 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来;
  • 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能;
  • 物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析;
  • 视频直播,使用 MongoDB 存储用户信息、礼物信息等;
  • 大数据应用,使用云数据库 MongoDB 作为大数据的云存储系统,随时进行数据提取分析,掌握行业动态。

当前业务是否适合使用 MongoDB?

没有某个业务场景必须要使用 MongoDB 才能解决,但使用 MongoDB 通常能让你以更低的成本解决问题。如果你不清楚当前业务是否适合使用 MongoDB,可以通过做几道选择题来辅助决策。

应用特征Yes/No
应用不需要复杂/长事务及 join 支持必须 Yes
新应用,需求会变,数据模型无法确定,想快速迭代开发?
应用需要 2000-3000 以上的读写 QPS(更高也可以)?
应用需要 TB 甚至 PB 级别数据存储?
应用发展迅速,需要能快速水平扩展?
应用要求存储的数据不丢失?
应用需要 99.999% 高可用?
应用需要大量的地理位置查询、文本查询?

只要有一项需求满足就可以考虑使用 MongoDB,匹配越多,选择 MongoDB 越合适。

MongoDB 环境搭建

linux 安装 MongoDB

1)环境准备

linux系统:centos7
安装 MongoDB 社区版

# 查看linux版本
[root@hecs-403280 ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

2)下载 MongoDB Community Server

下载地址:https://www.mongodb.com/try/download/community

image.png

# 下载MongoDB
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-6.0.5.tgz
tar -zxvf mongodb-linux-x86_64-rhel70-6.0.5.tgz

3)启动 MongoDB Server

# 创建dbpath和logpath
[root@hecs-403280 mongodb]# pwd
/usr/local/mongodb
[root@hecs-403280 mongodb]# mkdir -p data log
[root@hecs-403280 mongodb]# ls
bin  data  LICENSE-Community.txt  log  MPL-2  README  THIRD-PARTY-NOTICES# 进入mongodb目录,启动mongodb服务
bin/mongod --port=27017 --dbpath=/usr/local/mongodb/data --logpath=/usr/local/mongodb/log/mongodb.log --bind_ip=0.0.0.0 --fork

–dbpath:指定数据文件存放目录
–logpath:指定日志文件,注意是指定文件不是目录
–logappend:使用追加的方式记录日志
–port:指定端口,默认为27017
–bind_ip:默认只监听localhost网卡
–fork:后台启动
–auth:开启认证模式

image.png

4)添加环境变量
修改/etc/profile,添加环境变量,方便执行 MongoDB 命令

export MONGODB_HOME=/usr/local/mongodb
PATH=$PATH:$MONGODB_HOME/bin   

然后执行 source /etc/profile 重新加载环境变量。

5)利用配置文件启动服务
编辑/usr/local/mongodb/conf/mongo.conf文件,内容如下:

systemLog:destination: filepath: /usr/local/mongodb/log/mongod.log # log pathlogAppend: true
storage:dbPath: /usr/local/mongodb/data # data directoryengine: wiredTiger  #存储引擎journal:            #是否启用journal日志enabled: true
net:bindIp: 0.0.0.0port: 27017 # port
processManagement:fork: true

注意:一定要yaml格式。
启动 mongod:

mongod -f /usr/local/mongodb/conf/mongo.conf

-f 选项表示将使用配置文件启动 mongodb。

6)关闭 MongoDB 服务
方式 1:

mongod --port=27017 --dbpath=/usr/local/mongodb/data --shutdown

方式 2:
进入 mongosh

use admin
# 关闭 MongoDB server 服务
db.shutdownServer()

mongosh 使用

mongosh 是 MongoDB 的交互式 JavaScript Shell 界面,它为系统管理员提供了强大的界面,并为开发人员提供了直接测试数据库查询和操作的方法。
注意:MongoDB 6.0 移除了mongo,使用 mongosh。

mongosh 下载地址:https://www.mongodb.com/try/download/shell

# centos7 安装mongosh
wget https://downloads.mongodb.com/compass/mongodb-mongosh-1.8.0.x86_64.rpm
yum install -y mongodb-mongosh-1.8.0.x86_64.rpm
# 连接mongodb server端
# mongosh --host=192.168.65.206 --port=27017 
# mongosh 192.168.65.206:27017
# 指定uri方式连接
# mongosh mongodb://192.168.65.206:27017/test
mongosh

–port:指定端口,默认为27017
–host:连接的主机地址,默认127.0.0.1

image.png

mongosh 常用命令

命令说明
show dbs | show databases显示数据库列表
use 数据库名切换数据库,如果不存在创建数据库
db.dropDatabase()删除数据库
show collections | show tables显示当前数据库的集合列表
db.集合名.stats()查看集合详情
db.集合名.drop()删除集合
show users显示当前数据库的用户列表
show roles显示当前数据库的角色列表
show profile显示最近发生的操作
load(“xxx.js”)执行一个 JavaScript 脚本文件
exit | quit退出当前 shell
help查看 mongodb 支持哪些命令
db.help()查询当前数据库支持的方法
db.集合名.help()显示集合的帮助信息
db.version()查看数据库版本

数据库操作

# 查看所有库
show dbs
# 切换到指定数据库,不存在则创建
use test
# 删除当前数据库  
db.dropDatabase()

集合操作

# 查看集合
show collections
# 创建集合
db.createCollection("emp")
# 删除集合
db.emp.drop()

创建集合语法

db.createCollection(name, options)

options 参数:

字段类型描述
capped布尔(可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。
size数值(可选)为固定集合指定一个最大值(以字节计)。
如果 capped 为 true,也需要指定该字段。
max数值(可选)指定固定集合中包含文档的最大数量。

注意:当集合不存在时,向集合中插入文档也会创建集合。

安全认证

使用用户名和密码来认证用户身份是 MongoDB 中最常用的安全认证方式。可以通过以下步骤实现:

  • 创建一个管理员用户(root)并设置密码,具有所有数据库的管理权限。
  • 创建一个或多个普通用户,指定相应的数据库和集合权限,并设置密码。

启用认证后,客户端连接 MongoDB 服务器时需要提供用户名和密码才能成功连接。

创建管理员用户

# 设置管理员用户名密码需要切换到admin库
use admin  
# 创建管理员
db.createUser({user:"firechou",pwd:"firechou",roles:["root"]})
# 查看当前数据库所有用户信息 
show users 
# 显示可设置权限
show roles 
# 显示所有用户
db.system.users.find()

image.png

常用权限

权限名描述
read允许用户读取指定数据库
readWrite允许用户读写指定数据库
dbAdmin允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问 system.profile
dbOwner允许用户在指定数据库中执行任意操作,增、删、改、查等
userAdmin允许用户向 system.users 集合写入,可以在指定数据库里创建、删除和管理用户
clusterAdmin只在 admin 数据库中可用,赋予用户所有分片和复制集相关函数的管理权限
readAnyDatabase只在 admin 数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase只在 admin 数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase只在 admin 数据库中可用,赋予用户所有数据库的 userAdmin 权限
dbAdminAnyDatabase只在 admin 数据库中可用,赋予用户所有数据库的 dbAdmin 权限
root只在 admin 数据库中可用。超级账号,超级权限

重新赋予用户操作权限:

db.grantRolesToUser( "firechou" , [ { role: "clusterAdmin", db: "admin" } ,{ role: "userAdminAnyDatabase", db: "admin"},{ role: "readWriteAnyDatabase", db: "admin"} ])

删除用户:

db.dropUser("firechou")
# 删除当前数据库所有用户
db.dropAllUser()

用户认证,返回 1 表示认证成功:
image.png

创建应用数据库用户

use appdb
db.createUser({user:"appdb",pwd:"firechou",roles:["dbOwner"]})

MongoDB 启用鉴权

默认情况下,MongoDB 不会启用鉴权,以鉴权模式启动 MongoDB:

mongod -f /usr/local/mongodb/conf/mongo.conf --auth

启用鉴权之后,连接 MongoDB 的相关操作都需要提供身份认证。

mongosh 192.168.65.206:27017 -u firechou -p firechou --authenticationDatabase=admin

Docker 安装 MongoDB

https://hub.docker.com/_/mongo?tab=description&page=3

# 拉取mongo镜像
docker pull mongo:6.0.5
# 运行mongo镜像
docker run --name mongo-server -p 29017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=firechou \
-e MONGO_INITDB_ROOT_PASSWORD=firechou \
-d mongo:6.0.5 --wiredTigerCacheSizeGB 1

默认情况下,Mongo 会将 wiredTigerCacheSizeGB 设置为与主机总内存成比例的值,而不考虑你可能对容器施加的内存限制。
MONGO_INITDB_ROOT_USERNAME 和 MONGO_INITDB_ROOT_PASSWORD 都存在就会启用身份认证(mongod --auth)
利用 mongosh 建立连接:

# 远程连接
mongosh ip:29017 -u firechou -p firechou

MongoDB 常用工具

GUI 工具

(1)官方GUI:COMPASS
MongoDB 图形化管理工具(GUI),能够帮助您在不需要知道 MongoDB 查询语法的前提下,便利地分析和理解您的数据库模式,并且帮助您可视化地构建查询。

下载地址:https://www.mongodb.com/zh-cn/products/compass

image.png

(2)Robo 3T(免费)

下载地址:https://robomongo.org/

(3)Studio 3T(收费,试用30天)

下载地址:https://studio3t.com/download/

MongoDB Database Tools

下载地址:https://www.mongodb.com/try/download/database-tools

文件名称作用
mongostat数据库性能监控工具
mongotop热点表监控工具
mongodump数据库逻辑备份工具
mongorestore数据库逻辑恢复工具
mongoexport数据导出工具
mongoimport数据导入工具
bsondumpBSON 格式转换工具
mongofilesGridFS 文件工具

MongoDB 文档操作

SQL to MongoDB Mapping Chart :https://www.mongodb.com/docs/manual/reference/sql-comparison/

插入文档

MongoDB 提供了以下方法将文档插入到集合中:

  • db.collection.insertOne ():将单个文档插入到集合中。
  • db.collection.insertMany ():将多个文档插入到集合中。

新增单个文档

  • insertOne:用于向集合中插入一条文档数据,支持 writeConcern。语法如下:
db.collection.insertOne(<document>,{writeConcern: <document>}
)

image.png
设置 writeConcern 参数的示例:

db.emps.insertOne({ name: "firechou", age: 33},{writeConcern: { w: "majority", j: true, wtimeout: 5000 }}
)

image.png
writeConcern 是 MongoDB 中用来控制写入确认的选项。以下是 writeConcern 参数的一些常见选项:

w:指定写入确认级别。如果指定为数字,则表示要等待写入操作完成的节点数。如果指定为 majority,则表示等待大多数节点完成写入操作。默认为 1,表示等待写入操作完成的节点数为 1。
j:表示写入操作是否要求持久化到磁盘。如果设置为 true,则表示写入操作必须持久化到磁盘后才返回成功。如果设置为 false,则表示写入操作可能在数据被持久化到磁盘之前返回成功。默认为 false。
wtimeout:表示等待写入操作完成的超时时间,单位为毫秒。如果超过指定的时间仍然没有返回确认信息,则返回错误。默认为 0,表示不设置超时时间。

批量新增文档

  • insertMany:向指定集合中插入多条文档数据
db.collection.insertMany([ <document 1> , <document 2>, ... ],{writeConcern: <document>,ordered: <boolean>      }
)

writeConcern:写入确认选项,可选。
ordered:指定是否按顺序写入,默认 true,按顺序写入。

db.emps.insertMany([{x:1},{y:5}])

image.png

测试:批量插入 50 条随机数据
编辑脚本 book.js:

var tags = ["nosql","mongodb","document","developer","popular"];
var types = ["technology","sociality","travel","novel","literature"];
var books=[];
for(var i=0;i<50;i++){var typeIdx = Math.floor(Math.random()*types.length);var tagIdx = Math.floor(Math.random()*tags.length);var favCount = Math.floor(Math.random()*100);var book = {title: "book-"+i,type: types[typeIdx],tag: tags[tagIdx],favCount: favCount,author: "xxx"+i};books.push(book)
}
db.books.insertMany(books);

进入 mongosh,执行:

load("books.js")

image.png

查询文档

查询集合中的若干文档
语法格式如下:

db.collection.find(query, projection)

query:可选,使用查询操作符指定查询条件
projection:可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,只需省略该参数即可(默认省略)。投影时,_id 为 1 的时候,其他字段必须是 1;_id 是 0 的时候,其他字段可以是 0;如果没有 _id 字段约束,多个其他字段必须同为 0 或同为 1。

如果查询返回的条目数量较多,mongosh 则会自动实现分批显示。默认情况下每次只显示 20 条,可以输入 it 命令读取下一批。
image.png

查询集合中的第一个文档

语法格式如下:

db.collection.findOne(query, projection)

示例:

db.books.findOne()
db.books.find({tag:"nosql"},{title:1,author:1})

image.png
如果你需要以易读的方式来读取数据,可以使用 pretty 方法,语法格式如下:

db.collection.find().pretty()

注意:pretty() 方法以格式化的方式来显示所有文档。

条件查询

查询条件对照表:

**SQL **MQL
a = 1{a: 1}
a <> 1{a: {$ne: 1}}
a > 1{a: {$gt: 1}}
a >= 1{a: {$gte: 1}}
a < 1{a: {$lt: 1}}
a <= 1{a: {$lte: 1}}

查询逻辑对照表:

**SQL **MQL
a = 1 AND b = 1{a: 1, b: 1}或{$and: [{a: 1}, {b: 1}]}
a = 1 OR b = 1{$or: [{a: 1}, {b: 1}]}
a IS NULL{a: {$exists: false}}
a IN (1, 2, 3){a: {$in: [1, 2, 3]}}

查询逻辑运算符:

$lt: 存在并小于
$lte: 存在并小于等于
$gt: 存在并大于
$gte: 存在并大于等于
$ne: 不存在或存在但不等于
$in: 存在并在指定数组中
$nin: 不存在或不在指定数组中
$or: 匹配两个或多个条件中的一个
$and: 匹配全部条件

# 查询带有nosql标签的book文档:
db.books.find({tag:"nosql"})
# 按照id查询单个book文档:
db.books.find({_id:ObjectId("6596c598e226cbe365ee4796")})
# 查询分类为“travel”、收藏数超过60个的book文档:
db.books.find({type:"travel",favCount:{$gt:60}})

正则表达式匹配查询

MongoDB 使用 $regex 操作符来设置匹配字符串的正则表达式。

# 使用正则表达式查找type包含 so 字符串的book
db.books.find({type:{$regex:"so"}})
# 或者
db.books.find({type:/so/})

排序

在 MongoDB 中使用 sort() 方法对数据进行排序

# 指定按收藏数(favCount)降序返回
db.books.find({type:"travel"}).sort({favCount:-1})

1 为升序排列,而 -1 是用于降序排列

image.png

分页

skip 用于指定跳过记录数,limit 则用于限定返回结果数量。可以在执行 find 命令的同时指定 skip、limit 参数,以此实现分页的功能。
比如,假定每页大小为 8 条,查询第 3 页的 book 文档:

db.books.find().skip(16).limit(8)

.skip(16) 表示跳过前面 16 条记录,即前两页的所有记录。
.limit(8) 表示返回 8 条记录,即第三页的所有记录。

(1)处理分页问题-巧分页
数据量大的时候,应该避免使用 skip/limit 形式的分页。
替代方案:使用查询条件+唯一排序条件。
例如:

# 第一页
db.books.find({}).sort({_id: 1}).limit(10); 
# 第二页
db.books.find({_id: {$gt: <第一页最后一个_id>}}).sort({_id: 1}).limit(10); 
# 第三页
db.books.find({_id: {$gt: <第二页最后一个_id>}}).sort({_id: 1}).limit(10);

(2)处理分页问题–避免使用 count
尽可能不要计算总页数,特别是数据量大和查询条件不能完整命中索引时。
考虑以下场景:假设集合总共有 1000w 条数据,在没有索引的情况下考虑以下查询:

db.coll.find({x: 100}).limit(50);
db.coll.count({x: 100}); 

前者只需要遍历前 n 条,直到找到 50 条 x=100 的文档即可结束;
后者需要遍历完 1000w 条找到所有符合要求的文档才能得到结果。为了计算总页数而进行的 count() 往往是拖慢页面整体加载速度的原因;

更新文档

MongoDB 提供了以下方法来更新集合中的文档:

  • db.collection.updateOne ()

即使多个文档可能与指定的筛选器匹配,也只会更新第一个匹配的文档。

  • db.collection.updateMany ()

更新与指定筛选器匹配的所有文档。

更新操作符:

操作符格式描述
$set{$set:{field:value}}指定一个键并更新值,若键不存在则创建
$unset{$unset : {field : 1 }}删除一个键
$inc{$inc : {field : value } }对数值类型进行增减
$rename{$rename : {old_field_name : new_field_name } }修改字段名称
$push{ $push : {field : value } }将数值追加到数组中,若数组不存在则会进行初始化
$pushAll{$pushAll : {field : value_array }}追加多个值到一个数组字段内
$pull{$pull : {field : _value } }从数组中删除指定的元素
$addToSet{$addToSet : {field : value } }添加元素到数组中,具有排重功能
$pop{$pop : {field : 1 }}删除数组的第一个或最后一个元素

更新单个文档

updateOne 语法如下:

db.collection.updateOne(<filter>,<update>,{upsert: <boolean>,writeConcern: <document>,collation: <document>,arrayFilters: [ <filterdocument1>, ... ],hint:  <document|string>        // Available starting in MongoDB 4.2.1}
)

db.collection.updateOne() 方法的参数含义如下:

:一个筛选器对象,用于指定要更新的文档。只有与筛选器对象匹配的第一个文档才会被更新。
:一个更新操作对象,用于指定如何更新文档。可以使用一些操作符,例如 s e t 、 set、 setinc、 u n s e t 等,以更新文档中的特定字段。 u p s e r t :一个布尔值,用于指定如果找不到与筛选器匹配的文档时是否应插入一个新文档。如果 u p s e r t 为 t r u e ,则会插入一个新文档。默认值为 f a l s e 。 w r i t e C o n c e r n :一个文档,用于指定写入操作的安全级别。可以指定写入操作需要到达的节点数或等待写入操作的时间。 c o l l a t i o n :一个文档,用于指定用于查询的排序规则。例如,可以通过指定 l o c a l e 属性来指定语言环境,从而实现基于区域设置的排序。 a r r a y F i l t e r s :一个数组,用于指定要更新的数组元素。数组元素是通过使用更新操作符 unset 等,以更新文档中的特定字段。 upsert:一个布尔值,用于指定如果找不到与筛选器匹配的文档时是否应插入一个新文档。如果 upsert 为 true,则会插入一个新文档。默认值为 false。 writeConcern:一个文档,用于指定写入操作的安全级别。可以指定写入操作需要到达的节点数或等待写入操作的时间。 collation:一个文档,用于指定用于查询的排序规则。例如,可以通过指定 locale 属性来指定语言环境,从而实现基于区域设置的排序。 arrayFilters:一个数组,用于指定要更新的数组元素。数组元素是通过使用更新操作符 unset等,以更新文档中的特定字段。upsert:一个布尔值,用于指定如果找不到与筛选器匹配的文档时是否应插入一个新文档。如果upserttrue,则会插入一个新文档。默认值为falsewriteConcern:一个文档,用于指定写入操作的安全级别。可以指定写入操作需要到达的节点数或等待写入操作的时间。collation:一个文档,用于指定用于查询的排序规则。例如,可以通过指定locale属性来指定语言环境,从而实现基于区域设置的排序。arrayFilters:一个数组,用于指定要更新的数组元素。数组元素是通过使用更新操作符[]和$来指定的。
hint:一个文档或字符串,用于指定查询使用的索引。该参数仅在 MongoDB 4.2.1 及以上版本中可用。
注意,除了 filter 和 update 参数外,其他参数都是可选的。

某个 book 文档被收藏了,则需要将该文档的 favCount 字段自增:

db.books.updateOne({_id:ObjectId("6596c598e226cbe365ee47ac")},{$inc:{favCount:1}})

image.png
upsert 是一种特殊的更新,其表现为如果目标文档不存在,则执行插入命令。

db.books.updateOne({title:"my book"},{$set:{tags:["nosql","mongodb"],type:"none",author:"firechou"}},{upsert:true}
)

更新多个文档

updateMany 更新与集合的指定筛选器匹配的所有文档.
将分类为“novel”的文档的增加发布时间(publishedDate):

db.books.updateMany({type:"novel"},{$set:{publishedDate:new Date()}})

(1)findAndModify
findAndModify 兼容了查询和修改指定文档的功能,findAndModify 只能更新单个文档:

# 将某个book文档的收藏数(favCount)加1
db.books.findAndModify({query:{_id:ObjectId("6457a39c817728350ec83b9d")},update:{$inc:{favCount:1}}
})

该操作会返回符合查询条件的文档数据,并完成对文档的修改。
默认情况下,findAndModify 会返回修改前的“旧”数据。如果希望返回修改后的数据,则可以指定 new 选项:

db.books.findAndModify({query:{_id:ObjectId("6457a39c817728350ec83b9d")},update:{$inc:{favCount:1}},new: true
})

与 findAndModify 语义相近的命令如下:

  • findOneAndUpdate:更新单个文档并返回更新前(或更新后)的文档。
  • findOneAndReplace:替换单个文档并返回替换前(或替换后)的文档。

删除文档

deleteOne & deleteMany

官方推荐使用 deleteOne() 和 deleteMany() 方法删除文档,语法格式如下:

# 删除 type 等于 novel 的一个文档
db.books.deleteOne({ type:"novel" })
# 删除集合下全部文档
db.books.deleteMany({})
# 删除 type等于 novel 的全部文档
db.books.deleteMany({ type:"novel" })

注意:remove、deleteMany 命令需要对查询范围内的文档逐个删除,如果希望删除整个集合,则使用 drop 命令会更加高效。

findOneAndDelete

deleteOne 命令在删除文档后只会返回确认性的信息,如果希望获得被删除的文档,则可以使用 findOneAndDelete 命令:

db.books.findOneAndDelete({type:"novel"})

除了在结果中返回删除文档,findOneAndDelete 命令还允许定义“删除的顺序”,即按照指定顺序删除找到的第一个文档。利用这个特性,findOneAndDelete 可以实现队列的先进先出:

db.books.findOneAndDelete({type:"novel"},{sort:{favCount:1}})

批量操作

bulkwrite() 方法提供了执行批量插入、更新和删除操作的能力。
bulkWrite() 支持以下写操作:

  • insertOne
  • updateOne
  • updateMany
  • replaceOne
  • deleteOne
  • deleteMany

每个写操作都作为数组中的文档传递给 bulkWrite()。

db.pizzas.insertMany( [{ _id: 0, type: "pepperoni", size: "small", price: 4 },{ _id: 1, type: "cheese", size: "medium", price: 7 },{ _id: 2, type: "vegan", size: "large", price: 8 }
] )db.pizzas.bulkWrite( [{ insertOne: { document: { _id: 3, type: "beef", size: "medium", price: 6 } } },{ insertOne: { document: { _id: 4, type: "sausage", size: "large", price: 10 } } },{ updateOne: {filter: { type: "cheese" },update: { $set: { price: 8 } }} },{ deleteOne: { filter: { type: "pepperoni"} } },{ replaceOne: {filter: { type: "vegan" },replacement: { type: "tofu", size: "small", price: 4 }} }] )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/235617.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据采集与预处理】流数据采集工具Flume

目录 一、Flume简介 &#xff08;一&#xff09;Flume定义 &#xff08;二&#xff09;Flume作用 二、Flume组成架构 三、Flume安装配置 &#xff08;一&#xff09;下载Flume &#xff08;二&#xff09;解压安装包 &#xff08;三&#xff09;配置环境变量 &#xf…

python高校舆情分析系统+可视化+情感分析 舆情分析+Flask框架(源码+文档)✅

毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路&#xff0c;大家在毕设选题&#xff…

适用于 Windows 的 12 个最佳免费磁盘分区管理器软件

分区是与其他部分分开的硬盘驱动器部分。它使您能够将硬盘划分为不同的逻辑部分。分区软件是一种工具&#xff0c;可帮助您执行基本选项&#xff0c;例如创建、调整大小和删除物理磁盘的分区。许多此类程序允许您更改磁盘片的标签以便于识别数据。 适用于 Windows 的 12 个最佳…

【PaperReading】3. PTP

Category Content 论文题目 Position-guided Text Prompt for Vision-Language Pre-training Code: ptp 作者 Alex Jinpeng Wang (Sea AI Lab), Pan Zhou (Sea AI Lab), Mike Zheng Shou (Show Lab, National University of Singapore), Shuicheng Yan (Sea AI Lab) 另一篇…

爬虫01-爬虫原理以及爬虫前期准备工作

文章目录 1 爬虫基本原理什么是爬虫爬虫功能详解爬虫基本流程两个概念&#xff1a;request和response 2 一些问题爬虫能抓取什么样的数据&#xff1f;抓取的数据怎么提取部分内容&#xff1f;数据解析方式。为什么我爬虫抓取的数据和浏览器看到的不一样怎样解决JavaScript渲染的…

计算数学表达式的程序(Java课程设计)

1. 课设团队介绍 团队名称 团队成 员介绍 任务分配 团队成员博客 XQ Warriors 徐维辉 负责计算器数据的算法操作&#xff0c;如平方数、加减乘除&#xff0c;显示历史计算记录 无 邱良厦&#xff08;组长&#xff09; 负责计算器的图形设计&#xff0c;把输入和结果显…

公共用例库计划--个人版(二)主体界面设计

1、任务概述 计划内容&#xff1a;完成公共用例库的开发实施工作&#xff0c;包括需求分析、系统设计、开发、测试、打包、运行维护等工作。 1.1、 已完成&#xff1a; 需求分析、数据库表的设计&#xff1a;公共用例库计划–个人版&#xff08;一&#xff09; 1.2、 本次待完…

2024新年烟花代码完整版

文章目录 前言烟花效果展示使用教程查看源码HTML代码CSS代码JavaScript 新年祝福 前言 在这个充满希望和激动的2024年&#xff0c;新的一年即将拉开帷幕&#xff0c;而数字科技的创新与发展也如火如荼。烟花绚丽多彩的绽放&#xff0c;一直以来都是新年庆典中不可或缺的元素。…

微信小程序 组件component ts用法

还在为 使用了ts 但是组件内显示this.setData/this.data.xxx ts报错 觉得难看吗&#xff1f; 还在为明明定义了applyInfo&#xff0c;明明应该有setData为何报错&#xff1f; 还在为不知道如何写类型而烦心吗&#xff1f; 不如转变思路将methods看成为一个对象 增加断言 as a…

实现多级缓存(Redis+Caffeine)

文章目录 多级缓存的概述多级缓存的优势 多级缓存的概述 在高性能的服务架构设计中&#xff0c;缓存是一个不可或缺的环节。在实际的项目中&#xff0c;我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中&#xff0c;只有当缓存的访问没有命中时再查询数据库。在…

公网环境使用移动端设备+cpolar远程访问本地群晖nas上的影视资源

文章目录 1.使用环境要求&#xff1a;2.下载群晖videostation&#xff1a;3.公网访问本地群晖videostation中的电影&#xff1a;4.公网条件下使用电脑浏览器访问本地群晖video station5.公网条件下使用移动端&#xff08;搭载安卓&#xff0c;ios&#xff0c;ipados等系统的设备…

小家电应用解决方案以及选型指南

电磁炉是现代厨房中常见的一种小家电产品&#xff0c;它利用电磁感应加热原理&#xff0c;可以快速、高效地进行烹饪。在电磁炉的设计和制造过程中&#xff0c;功率开关芯片的选择对于产品的性能和成本有着重要的影响。 针对电磁炉的应用需求&#xff0c;推荐采用LED驱动芯片S…

蓝桥杯省赛无忧 STL 课件12 vector

01 vector的定义和特性 02 vector的常用函数 03 vector排序去重 示例&#xff1a; #include<bits/stdc.h> using namespace std; int main(){vector<int> vec {5,2,8,1,9};sort(vec.begin(),vec.end());for(const auto& num : vec){cout<<num<<&q…

Centos7升级openssl到openssl1.1.1

Centos7升级openssl到openssl1.1.1 1、先查看openssl版本&#xff1a;openssl version 2、Centos7升级openssl到openssl1.1.1 升级步骤 #1、更新所有现有的软件包列表并安装最新的软件包&#xff1a; $sudo yum update #2、接下来&#xff0c;我们需要从源代码编译和构建OpenS…

【原生部署】SpringBoot+Vue前后端分离项目

本次主要讲解SpringBootVue前后端完全分离项目在CentOS云服务器上的环境搭建与部署过程&#xff0c;我们主要讲解原生部署。 一.原生部署概念 原生部署是指将应用程序&#xff08;一般是指软件、应用或服务&#xff09;在底层的操作系统环境中直接运行和部署&#xff0c;而不…

微软Office 2019 批量授权版

软件介绍 微软办公软件套件Microsoft Office 2019 专业增强版2024年1月批量许可版更新推送&#xff01;Office2019正式版2018年10月份推出&#xff0c;主要为多人跨平台办公与团队协作打造。Office2019整合对过去三年在Office365里所有功能&#xff0c;包括对Word、Excel、Pow…

Docker的介绍及安装基本操作命令

前言 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全使用沙箱…

基于Selenium+Python的web自动化测试框架

一、什么是Selenium&#xff1f; Selenium是一个基于浏览器的自动化测试工具&#xff0c;它提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。Selenium主要包括三部分&#xff1a;Selenium IDE、Selenium WebDriver 和Selenium Grid。 Selenium IDE&#xff1a;Firefo…

阿里云和AWS之间的应用程序防火墙比较及选择建议!

对于大多数开发人员来说&#xff0c;托管在云中的 Web 应用程序或 REST API 是一种常见方案。但是&#xff0c;并非每个应用程序都具有相同的安全级别。将 Web 应用程序防火墙 &#xff08;WAF&#xff09; 添加到 Web 应用程序是提高安全性的有用方法。 在本文中&#xff0c;…

Python实用小工具(4)——邮件轰炸机,给朋友搞点乐子(附源码+exe文件)

欢迎来到MatpyMaster&#xff01;今天我们将使用Python来批量发送邮件&#xff0c;让你的邮件推送变得更加高效。废话不多说&#xff0c;直接开搞&#xff01;使用声明&#xff1a; 请确保你的邮箱开启了SMTP服务&#xff0c;并获取了授权码。 选择合适的发送间隔&#xff0c;…