MongoDB实战

1.MongoDB介绍

1.1 什么是MongoDB

MongoDB是一个文档数据库(以JSON 为数据模型),由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。

文档来自于"JSON Document",并非我们一般理解的 PDF,WORD文档。

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,数据格式是BSON,一种类似ISON的二进制形式的存储格式,简称BinaryJSON,和JSON一样支持内嵌的文档对象和数组对象,因此可以存储比较复杂的数据类型。MongoDB最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。原则上 Oracle 和 MySQL 能做的事情,MongoDB 都能做(包括 ACID事务)。

MongoDB在数据库总排名第5,仅次于Oracle、MySQL等RDBMS,在NoSQL数据库排名首位。从诞生以来,其项目应用广度、社区活跃指数持续上升。

Rank

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中的视图类似。从MongoDB 3.4版本开始提供了视图功能,其通过聚合管道技术实现。
  • 聚合操作($lookup):MongoDB用于实现 “类似” 表连接(tablejoin)的聚合操作符。

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

  • 半结构化,在一个集合中,文档所拥有的字段并不需要是相同的,而且也不需要对所用的字段进行声明。因此,MongDB具有很明显的半结构化特点。除了松散的表结构,文档还可以支持多级的嵌套、数组等灵活的数据类型,非常契合面向对象的编程模型。
  • 弱关系,MongoDB没有外键的约束,也没有非常强大的表连接能力。类似的功能需要使用聚合管道技术来弥补。
MongoDB关系型数据库
亿级以上数据量轻松支持要努力一下,分库分表
灵活表结构轻松支持Entity Key/Value ,关联查询比较痛苦
高并发读轻松支持需要优化
高并发写轻松支持需要优化
跨地区集群轻松支持需要定制方案
分片集群轻松支持需要中间件
地理位置查询比较完整的地理位置PG还可以,其他数据库略麻烦
聚合计算功能很强大使用Group By等,能力有限
异构数据轻松支持使用EKV属性表
大宽表轻松支持性能受限

1.2 MongoDB技术优势

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

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

简单直观: 从错综复杂的关系模型到一目了然的对象模型

在这里插入图片描述

快速: 最简单快速的开发方式

在这里插入图片描述

灵活: 快速响应业务变化

在这里插入图片描述

MongoDB优势:原生的高可用

在这里插入图片描述

MongoDB优势:横向扩展能力

在这里插入图片描述

1.3 MongoDB应用场景

从目前阿里云 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越合适。

2.MongoDB快速开始

2.1 Linux安装MongoDB

环境准备

  • Linux系统: centos7
  • 安装MongoDB社区版

下载MongoDB Community Server

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

在这里插入图片描述

#下载MongoDB
wget https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-4.4.28.tgz
tar -zxvf mongodb-macos-x86_64-4.4.28.tgz
vim ~/.zshrc# 内容BEGIN
export PATH=/Users/zhinian/Desktop/tools/mongodb/bin:$PATH
# 内容ENDsource ~/.zshrc
./mongod --helpOptions:--networkMessageCompressors arg (=snappy,zstd,zlib)Comma-separated list of compressors to use for network messagesGeneral options:-h [ --help ]                         Show this usage information--version                             Show version information-f [ --config ] arg                   Configuration file specifying additional options--configExpand arg                    Process expansion directives in config file (none, exec, rest)--port arg                            Specify port number - 27017 by default--ipv6                                Enable IPv6 support (disabled by default)--listenBacklog arg (=128)            Set socket listen backlog size--maxConns arg (=1000000)             Max number of simultaneous connections--pidfilepath arg                     Full path to pidfile (if not set, no pidfile is created)--timeZoneInfo arg                    Full path to time zone info directory, e.g. /usr/share/zoneinfo--nounixsocket                        Disable listening on unix sockets--unixSocketPrefix arg                Alternative directory for UNIX domain sockets (defaults to /tmp)--filePermissions arg                 Permissions to set on UNIX domain socket file - 0700 by default--fork                                Fork server process-v [ --verbose ] [=arg(=v)]           Be more verbose (include multiple timesfor more verbosity e.g. -vvvvv)--quiet                               Quieter output--logpath arg                         Log file to send write to instead of stdout - has to be a file, not directory--syslog                              Log to system's syslog facility insteadof file or stdout--syslogFacility arg                  syslog facility used for mongodb syslogmessage--logappend                           Append to logpath instead of over-writing--logRotate arg                       Set the log rotation behavior (rename|reopen)--timeStampFormat arg                 Desired format for timestamps in log messages. One of iso8601-utc or iso8601-local--setParameter arg                    Set a configurable parameter--bind_ip arg                         Comma separated list of ip addresses tolisten on - localhost by default--bind_ip_all                         Bind to all ip addresses--noauth                              Run without security--transitionToAuth                    For rolling access control upgrade. Attempt to authenticate over outgoing connections and proceed regardless of success. Accept incoming connections with or without authentication.--slowms arg (=100)                   Value of slow for profile and console log--slowOpSampleRate arg (=1)           Fraction of slow ops to include in the profile and console log--profileFilter arg                   Query predicate to control which operations are logged and profiled--auth                                Run with security--clusterIpSourceWhitelist arg        Network CIDR specification of permittedorigin for `__system` access--profile arg                         0=off 1=slow, 2=all--cpu                                 Periodically show cpu and iowait utilization--sysinfo                             Print some diagnostic system information--noscripting                         Disable scripting engine--notablescan                         Do not allow table scans--keyFile arg                         Private key for cluster authentication--clusterAuthMode arg                 Authentication mode used for cluster authentication. Alternatives are (keyFile|sendKeyFile|sendX509|x509)Replication options:--oplogSize arg                       Size to use (in MB) for replication op log. default is 5% of disk space (i.e. large is good)Replica set options:--replSet arg                         arg is <setname>[/<optionalseedhostlist>]--enableMajorityReadConcern [=arg(=1)] (=1)Enables majority readConcernSharding options:--configsvr                           Declare this is a config db of a cluster; default port 27019; default dir /data/configdb--shardsvr                            Declare this is a shard db of a cluster; default port 27018Storage options:--storageEngine arg                   What storage engine to use - defaults to wiredTiger if no data files present--dbpath arg                          Directory for datafiles - defaults to /data/db--directoryperdb                      Each database will be stored in a separate directory--syncdelay arg (=60)                 Seconds between disk syncs--journalCommitInterval arg (=100)    how often to group/batch commit (ms)--upgrade                             Upgrade db if needed--repair                              Run repair on all dbs--journal                             Enable journaling--nojournal                           Disable journaling (journaling is on bydefault for 64 bit)--oplogMinRetentionHours arg (=0)     Minimum number of hours to preserve in the oplog. Default is 0 (turned off). Fractions are allowed (e.g. 1.5 hours)TLS Options:--tlsOnNormalPorts                    Use TLS on configured ports--tlsMode arg                         Set the TLS operation mode (disabled|allowTLS|preferTLS|requireTLS)--tlsCertificateKeyFile arg           Certificate and key file for TLS--tlsCertificateKeyFilePassword arg   Password to unlock key in the TLS certificate key file--tlsClusterFile arg                  Key file for internal TLS authentication--tlsClusterPassword arg              Internal authentication key file password--tlsCAFile arg                       Certificate Authority file for TLS--tlsClusterCAFile arg                CA used for verifying remotes during inbound connections--tlsCRLFile arg                      Certificate Revocation List file for TLS--tlsDisabledProtocols arg            Comma separated list of TLS protocols to disable [TLS1_0,TLS1_1,TLS1_2]--tlsAllowConnectionsWithoutCertificates Allow client to connect without presenting a certificate--tlsAllowInvalidHostnames            Allow server certificates to provide non-matching hostnames--tlsAllowInvalidCertificates         Allow connections to servers with invalid certificates--tlsFIPSMode                         Activate FIPS 140-2 mode at startup--tlsCertificateSelector arg          TLS Certificate in system store--tlsClusterCertificateSelector arg   SSL/TLS Certificate in system store forinternal TLS authentication--tlsLogVersions arg                  Comma separated list of TLS protocols to log on connect [TLS1_0,TLS1_1,TLS1_2]AWS IAM Options:--awsIamSessionToken arg              AWS Session Token for temporary credentialsWiredTiger options:--wiredTigerCacheSizeGB arg           Maximum amount of memory to allocate for cache; Defaults to 1/2 of physical RAM--wiredTigerJournalCompressor arg (=snappy)Use a compressor for log records [none|snappy|zlib|zstd]--wiredTigerDirectoryForIndexes       Put indexes and data in different directories--wiredTigerCollectionBlockCompressor arg (=snappy)Block compression algorithm for collection data [none|snappy|zlib|zstd]--wiredTigerIndexPrefixCompression arg (=1)Use prefix compression on row-store leaf pages

启动MongoDB Server

#创建dbpath和logpath
mkdir ‐p ~/Desktop/tools/mongodb-macos-x86_64-4.4.28/data ~/Desktop/tools/mongodb-macos-x86_64-4.4.28/log
#进入mongodb目录,启动mongodb服务
mongod --logpath="/Users/zhinian/Desktop/tools/mongodb/log/mongodb.log" --bind_ip="0.0.0.0" --dbpath="/Users/zhinian/Desktop/tools/mongodb/data" --port=27017 --fork# 以下为输出, 不是命令
about to fork child process, waiting until server is ready for connections.
forked process: 50386
child process started successfully, parent exiting
zhinian@192 ~ % mongo
MongoDB shell version v4.4.28
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("d68a44f7-6a0f-4b7e-9984-fe6954a37527") }
MongoDB server version: 4.4.28
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, seehttps://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forumshttps://community.mongodb.com
---
The server generated these startup warnings when booting: 2024-01-27T14:32:34.658+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted2024-01-27T14:32:34.659+08:00: Soft rlimits too low2024-01-27T14:32:34.659+08:00:         currentValue: 25602024-01-27T14:32:34.659+08:00:         recommendedMinimum: 64000
---
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

–dbpath:指定数据文件存放目录

–logpath:指定日志文件,注意是指定文件不是目录

–logappend:使用追加的方式记录日志

–port:指定端口,默认为27017

–bind_ip:默认只监听localhost网卡

–fork:后台启动

–auth:开启认证模式

在这里插入图片描述

利用配置文件启动服务

编辑/mongodb/conf/mongo.conf文件,内容如下:

vim ~/Desktop/tools/mongodb/conf/mongo.conf
systemLog:destination: filepath: /Users/zhinian/Desktop/tools/mongodb/log/mongod.10g # log pathlogAppend: true
storage:dbPath: /Users/zhinian/Desktop/tools/mongodb/data # data directoryengine: wiredTiger #存储引擎journal: #是否启用journa1日志enabled: true
net:bindIp: 0.0.0.0port: 27017 # port
processManagement:fork: true # fork and run in backgroundshutdown: true  # Add this line to shutdown the database
vim bins/mongodb
# 内容BEGIN
mongod -f /Users/zhinian/Desktop/tools/mongodb/conf/mongo.conf
# 内容END
chmod +x bins/mongodb
# 仅需要输入mongodb即可启动
zhinian@192 ~ % mongodb                                                   
about to fork child process, waiting until server is ready for connections.
forked process: 51981
child process started successfully, parent exiting

注意:一定要yaml格式

后动mongod

mongod -f/mongodb/conf/mongo.conf

关闭MongoDB服务

方式一

## 新版本已没有shutdown命令
mongod --port=27017 --dbpath=/Users/zhinian/Desktop/tools/mongodb/data --shutdownError parsing command line: unrecognised option '--shutdown'
try 'mongod --help' for more information

方式二

进入mongo shell

use admin
db.shutdownServer()

在这里插入图片描述

2.2 Mongo Shell 使用

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

mongo --port=27017

–port:指定端口,默认为27017

–host:连接的主机地址,默认127.0.0.1

在这里插入图片描述

Javascript支持

mongo shell是基于Javascript语法的,MongoDB使用了SpiderMonkey作为其内部的Javascript解释器引擎,这是由Mozilla官方提供的Javascript内核解释器,该解释器也被同样用于大名鼎鼎的Firefox浏览器产品之中。SpiderMonkey对ECMA Script标准兼容性非常好,以支持ECMA Script6。可以通过下面的命令检查JavaScript解释器的版本:

在这里插入图片描述

Mongo Shell常用命令

命令说明
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数值(可选)指定固定集合中包含文档的最大数量。

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

2.3 安全认证

创建管理员账号

# 设置管理员用户名/密码需要切换到admin库
use admin
# 创建管理员
db.createUser({user: "fox", pwd: "fox", roles: ["root"]})
# 查看所有用户信息
show users
# 删除用户
db.dropUser("fox")

在这里插入图片描述

常用权限

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

用户认证,返回1表示认证成功

在这里插入图片描述

创建应用数据库用户

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

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

mongod -f /Users/zhinian/Desktop/tools/mongodb/conf/mongo.conf --auth

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

mongo 192.168.1.3:27017 -uappdb -pfox --authenticationDatabase=appdb

在这里插入图片描述

3、MongoDB文档操作

3.1 插入文档

3.2 版本之后新增了 db.collection.insertOne() 和 db.collection.insertMany()。

新增单个文档

  • insertOne: 支持writeConcern
db.collection.insertOne(<document>,{writeConcern: <document>}
)

writeConcern 决定一个写操作落到多少个节点上才算成功。writeConcern 的取值包括:

0:发起写操作,不关心是否成功;

1-集群最大数据节点数:写操作需要被复制到指定节点数才算成功;

majority:写操作需要被复制到大多数节点上才算成功。

  • insert:若插入的数据主键已经存在,则会抛 DuplicatekeyException 异常,提示主键重复,不保存当前数据。
  • save:如果_jd 主键存在则更新数据,如果不存在就插入数据。

在这里插入图片描述

批量新增文档

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

writeConcern: 写入策略,默认为1,即要求确认写操作,0是不要求。

ordered: 指定是否按顺序写入,默认true,按顺序写入。

  • insert和save也可以实现批量插入

在这里插入图片描述

测试:批量插入50条随机数据

编辑脚本book.js

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

进入mongo shell,执行

load("book.js")

在这里插入图片描述

3.2 查询文档

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

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

在这里插入图片描述

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

findOne查询集合中的第一个文档。语法格式如下:

db.collection.findOne(query, projection)

在这里插入图片描述

条件查询

指定条件查询

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

查询条件对照表

SQLMQL
a = 1${a: 1}
a <> 1{a: {$ne: 1}}
a > 1{a: {$gt: 1}}
a >= 1{a: {$ge: 1}}
a < 1{a: {$lt: 1}}
a <= 1{a: {$lte: 1}}

查询逻辑对照表

SQLMQL
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:匹配全部条件

在这里插入图片描述

排序 & 分页

指定排序

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

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

分页查询

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

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

正则表达式匹配查询

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

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

3.3 更新文档

可以用update命令对指定的数据进行更新,命令的格式如下:

db.collection.update(query, update, options)
  • query:描述更新的查询条件;
  • update:描述更新的动作及新的内容;
  • options:描述更新的选项
    • upsert: 可选,如果不存在update的记录,是否插入新的记录。默认false,不插入
    • multi: 可选,是否按条件查询出的多条记录全部更新。默认false,只更新找到的第—条记录
    • writeConcernk可选,决定一个写操作落到多少个节点上才算成功。

更新操作符

操作符格式描述
$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}}删除数组的第一个或最后一个元素

更新单个文档

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

db.books.update({_id: ObjectId("65b4e219ebed3fc5e9d74287")}, {$inc: {favCount: 1}})

在这里插入图片描述

更新多个文档

默认情况下,update命令只在更新第一个文档之后返回,如果需要更新多个文档,则可以使用multi选项。

将分类为 “novel” 的文档的增加发布时间(publishedDate)

db.books.update({type: "nosql"}, {$set: {publishedDate: new Date()}}, {"multi": true})

multi: 可选,mongodb 默认是 false,只更新找到的第一条记录,如果这个参数为 true,就把按条件查询出的多条记录全部更新

在这里插入图片描述

update命令的选项配置较多,为了简化使用还可以使用一些快捷命令:

  • updateOne: 更新单个文档。
  • updateMany: 更新多个文档。
  • replaceOne: 替换单个文档。

使用upsert命令

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

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

nMatched、nModified都为0,表示没有文档被匹配及更新,nUpserted=1提示执行了upsert操作

在这里插入图片描述

实现replace语义

update命令中的更新描述(update)通常由操作符描述,如果更新描述中不包含任何的操作符,那么MongoDB会实现文档的replace语义

db.books.update({title: "my book"},{justTitle: "my first book"}
)

在这里插入图片描述

findAndModify命令

findAndModify兼容了查询和修改指定文档的功能,

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

该操作会返回符合查询条件的文档数据,并完成对文档的修改。

在这里插入图片描述

默认情况下,findAndModify会返回修改前的"旧"数据。如果希望返回修改后的数据,则可以指定new选项

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

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

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

3.4 删除文档

使用remove删除文档

  • remove 命令需要配合查询条件使用;
  • 匹配查询条件的文档会被删除;
  • 指定一个空文档条件会删除所有文档;

示例:

db.user.remove({age: 28}) -- 删除 age 等于 28 的记录
db.user.remove({age: {$lt: 25}}) -- 删除 age 小于 25 的记录
db.user.remove({}) -- 删除所有记录
db.user.remove() -- 报错

remove命令会删除匹配条件的全部文档,如果希望明确限定只删除一个文档,则需要指定justOne参数,命令格式如下:

db.collection.remove(query, justone)

例如:删除满足type:novel条件的首条记录(加true删首条)

db.books.remove({type: "novel"}, true)

使用delete删除文档

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

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

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

返回被删除文档

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

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

在这里插入图片描述

除了在结果中返回删除文档,findOneAndDelete命令还允许定义 “删除的顺序”,即按照指定顺序删除找到的第一个文档

db.books.findoneAndDelete({type: "nove1"}, {sort: {favcount:1}})

remove、deleteOne等命令能按默认顺序删除,利用这个特性,findOneAndDelete可以实现队列的先进先出。

4.MongoDB整合SpringBoot

4.1 环境准备

MongoDB Compass: https://www.mongodb.com/try/download/compass

1.引入依赖

<!-- Spring data mongodb -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

2.配置yml

spring:data:mongodb:uri: mongodb://fox:fox@192.168.1.3:27017/test?authSource=admin# uri等同于下面的配置# database: test# host: 192.168.1.3# port: 27017# username: fox# password: fox# authentication-database: admin

连接配置参考文档: https://docs.mongodb.com/manual/reference/connection-string/

3.使用时注入mongoTemplate

@Autowired
MongoTemplate mongoTemplate;

4.2 集合操作

/*** 创建集合*/
@Test
public void testCreateCollection() {final String collectionName = "emp";if (mongoTemplate.collectionExists(collectionName)) {mongoTemplate.dropCollection(collectionName);}mongoTemplate.createCollection(collectionName);
}

在这里插入图片描述

4.3 文档操作

相关注解

  • @Document

    • 修饰范围: 用在类上
    • 作用: 用来映射这个类的一个对象为mongo中一条文档数据。
    • 属性: (value、collection)用来指定操作的集合名称
  • @ld

    • 修饰范围: 用在成员变量、方法上
    • 作用: 用来将成员变量的值映射为文档的_id的值
  • @Field

    • 修饰范围: 用在成员变量、方法上
    • 作用: 用来将成员变量及其值映射为文档中一个key:value对。
    • 属性: (name,value)用来指定在文档中key的名称,默认为成员变量名
  • @Transient

    • 修饰范围;用在成员变量、方法上

    • 作用:用来指定此成员变量不参与文档的序列化

创建实体

@Data
@Document("emp") // 对应emp集合中的一个文档
@AllArgsConstructor
@NoArgsConstructor
public class Employee {@Id //映射文档中的_idprivate Long id;@Field("username")private String name;@Fieldprivate BigDecimal salary;@Fieldprivate Date birthday;
}

添加文档

insert方法返回值是新增的Document对象,里面包含了新增后id的值。如果集合不存在会自动创建集合。通过Spring Date MongoDB还会给集合中多加一个class的属性,存储新增时Document对应Java中类的全限定路径。这么做为了查询时能把Documnent转换力Java类型。

@Test
public void testInsert() {Employee emp = new Employee(1L, "小明", new BigDecimal("3010000.00"), new Date());// 添加文档// save: _id存在时更新数据// mongoTemplate.save(emp);// insert: _id存在时抛出异常, 支持批量操作mongoTemplate.insert(emp);List<Employee> list = Arrays.asList(new Employee(2L, "张三", new BigDecimal("2150000.00"), new Date()),new Employee(3L, "李四", new BigDecimal("2680000.00"), new Date()),new Employee(4L, "王五", new BigDecimal("2280000.00"), new Date()),new Employee(5L, "张龙", new BigDecimal("2860000.00"), new Date()),new Employee(6L, "赵虎", new BigDecimal("2470000.00"), new Date()),new Employee(7L, "赵六", new BigDecimal("2812000.00"), new Date()));// 插入多条数据mongoTemplate.insert(list, Employee.class);
}

查询文档

Criteria是标准查询的接口,可以引用静态的Criteria.where的把多个条件组合在一起,就可以轻松地将多个方法标准和查询连接起来,方便我们操作查询语句。

CriteriaMongodb说明
Criteria and (String key)$and井且
Criteria andOperator (Criteria... criteria)$and井且
Criteria orOperator (Criteria.. criteria)$or或者
Criteria gt (Object o)$gt大于
Criteria gte (Object o)$gte大于等于
Criteria in (Object... o)$in包含
Criteria is (Object o)$is等于
Criteria lt (Object o)$lt小于
Criteria lte (Object o)$lte小于等于
Criteria nin (Object... o)$nin不包含
@Test
public void testFind() {System.out.println("=============查询所有文档=============");// 查看所有文档List<Employee> list = mongoTemplate.findAll(Employee.class);list.forEach(System.out::println);System.out.println("==============根据id查询==============");// 根据id查询Employee emp = mongoTemplate.findById(1L, Employee.class);System.out.println(emp);System.out.println("==========findOne返回第一个文档==========");// 如果查询结果是多个, 返回其中第一个文档对象Employee one = mongoTemplate.findOne(new Query(), Employee.class);System.out.println(one);System.out.println("================条件查询================");// new Query() 表示没有条件// 查询薪资大于等于8000的员工// Query query = new Query(Criteria.where("salary").gte(8000.00));// 查询薪资大于4000小于10000的员工// Query query = new Query(Criteria.where("salary").gt(4000.00).lt(10000.00));// 正则查询(模糊查询) java中正则不需要有//// Query query = new Query(Criteria.where("name").regex("张"));// and or 多条件查询Criteria criteria = new Criteria();// and 查询年龄大于25&薪资大于8000的员工// criteria.andOperator(Criteria.where("age").gt(25), Criteria.where("salary").gt(8000.00));// or 查询姓名是张三或者薪资大于8000的员工criteria.orOperator(Criteria.where("name").is("张三"), Criteria.where("salary").gt(8000.00));Query query = new Query(criteria);// sort排序// query.with(Sort.by(Sort.Order.desc("salary")));// skip limit 分页 skip用于指定跳过记录数, limit 则用于限定返回结果数量。query.with(Sort.by(Sort.Order.desc("salary"))).skip(0)    // 指定跳过记录数.limit(4);  // 每页显示记录数// 查询结果List<Employee> employees = mongoTemplate.find(query, Employee.class);employees.forEach(System.out::println);
}
@Test
public void testFindByJSON() {// 使用JSON字符串方式查询// 等值查询// String json = "{name: '张三'}";// 多条件查询String json = "{$or: [{age: {$gt: 25}}, {salary: {$gte: 8000}}]}";Query query = new BasicQuery(json);// 查询结果List<Employee> employees = mongoTemplate.find(query, Employee.class);employees.forEach(System.out::println);
}

更新文档

在Mongodb中无论是使用客户端APi还是使用Spring Data,更新返回结果一定是受行数影响。如果更新后的结果和更新前的结果是相同,返旦0。

  • updateFirst() 只更新满足条件的第一条记录
  • updateMulti() 更新所有满足条件的记录
  • upsert() 没有符合条件的记录则插入数据
@Test
public void testUpdate() {// query设置查询条件Query query = new Query(Criteria.where("salary").gte(10000));System.out.println("==========更新前===========");List<Employee> employees = mongoTemplate.find(query, Employee.class);employees.forEach(System.out::println);Update update = new Update();// 设置更新属性update.set("salary", 14000);// updateFirst() 只更新满足条件的第一条记录// UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Employee.class);// updateMulti() 更新所有满足条件的记录// UpdateResult updateResult = mongoTemplate.updateMulti(query, update, Employee.class);// upsert() 没有符合条件的记录则插入数据update.setOnInsert("id", 11);   // 指定_idUpdateResult updateResult = mongoTemplate.upsert(query, update, Employee.class);// 返口修改的记录数System.out.println(updateResult.getModifiedCount());System.out.println("===============更新后===============");employees = mongoTemplate.find(query, Employee.class);employees.forEach(System.out::println);
}

删除文档

@Test
public void testDelete() {// 删除所有文档// mongoTemplate.remove(new Query(), Employee.class);// 条件删除Query query = new Query(Criteria.where("salary").gte(10000));mongoTemplate.remove(query, Employee.class);
}

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

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

相关文章

【MIdjourney】五个特殊物体关键词

1.碳酸(Carbonate) 这一词语的本意是指包含碳&#xff08;C&#xff09;、氧&#xff08;O&#xff09;和氢&#xff08;H&#xff09;元素的化合物。而在MIdjourney中添加该词汇会使得生成的图片具有水滴效果且富有动态感。 2.灯丝(Filament) Filament效果可能包括更逼真的…

java 基础学习1

目录 一.注释 二.关键字 三.字面量 四.变量和标识符 五.键盘录入 六.运算符 一.注释 1.单行注释&#xff1a;//注释信息 2.多行注释&#xff1a;/* 注释信息*/ 3.文档注释&#xff1a;/** 注释信息*/ 注:文档注释暂时用不上 二.关键字 关键字: 被Java赋予了特定…

Django介绍

一、介绍 Django是Python语言中的一个Web框架&#xff0c;Python语言中主流的web框架有Django、Tornado、Flask 等多种 优势&#xff1a;大而全&#xff0c;框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等功能&#xff0c;是一个全能型框架&#xff0c;拥有自己的A…

有趣的css - 好看的呼吸灯效果

整体效果 这个效果主要用 css3 的 animation 属性来实现的。 这个效果可以用作在网站的整体 Loading&#xff0c;也可以放在网站首屏当一个 banner 的背景也是非常棒的&#xff01; 代码部分 html 部分代码&#xff1a; <div class"app"><span class&quo…

【问题解决】java-word转pdf踩坑

问题情境&#xff1a; 项目中采用word转pdf&#xff0c;最开始使用的pdf相关的apache的pdfbox和itextpdf&#xff0c;后面发现对于有图片背景的word转pdf的情景&#xff0c;word中的背景图会直接占用位置&#xff0c;导致正文不会正确落在背景图上。 解决方案&#xff1a; 采…

研发日记,Matlab/Simulink避坑指南(八)——else if分支结构Bug

文章目录 前言 背景介绍 问题描述 分析排查 解决方案 总结归纳 前言 见《研发日记&#xff0c;Matlab/Simulink避坑指南(三)——向上取整Bug》 见《研发日记&#xff0c;Matlab/Simulink避坑指南(四)——transpose()转置函数Bug》 见《研发日记&#xff0c;Matlab/Simuli…

web前端---------盒子模型2

一------内边距 padding 属性用来设置元素的内边距长度&#xff0c;元素在默认情况下没有内边距&#xff0c;其值为none。 &#xff08;1&#xff09;当 padding 属性中仅含一个值时&#xff0c;该长度应用在上、下、左、右四个区域。 &#xff08;2&#xff09;当 padding …

vue3使用最新的属性defineModel实现父子组件数据响应式绑定

子父之间使用v-model双向绑定数据&#xff0c;子组件每次都要写emit和props觉得麻烦&#xff1f;以前&#xff0c;为了使组件支持与v-model双向绑定&#xff0c;它需要&#xff08;1&#xff09;声明prop&#xff0c;&#xff08;2&#xff09;在打算更新prop时发出相应的updat…

架构篇21:高性能负载均衡-算法

文章目录 轮询加权轮询负载最低优先性能最优类Hash 类源地址 HashID Hash小结负载均衡算法数量较多,而且可以根据一些业务特性进行定制开发,抛开细节上的差异,根据算法期望达到的目的,大体上可以分为下面几类。 任务平分类:负载均衡系统将收到的任务平均分配给服务器进行处…

【Vue】1-2、Webpack 中的插件

一、Webpack 插件的作用 通过安装和配置第三方的插件&#xff0c;可以拓展 webpack 的能力&#xff0c;从而让 webpack 用起来更方便。 二、两个常用插件 1&#xff09;webpack-dev-server 类似于 node.js 使用的 nodemon 工具 每当修改了源代码&#xff0c;webpack 会自动…

C++ 类的初始化列表

C 中的类必须使用初始化列表的 4 种情况&#xff1a; 一&#xff0c;继承于一个基类&#xff0c;这个基类的构造函数有参数时。 #include <stdio.h> #include <stdlib.h>#pragma pack(4) class CBase { public:CBase(int value): bBaseValue(value){}~CBase(){}p…

处理 Maven jar 包下载失败问题

目录 1、配置国内 Maven 源 配置和检测 settings.xml 配置国内源 2、删除本地 maven 创库的 jar 重新下载 3、其他问题 一般情况下 maven jar 包下载不成功可能有两种情况&#xff1a; 1&#xff09;没有配置国内源 2&#xff09;jar 包需要重新下载 下面详细讲解如何解决这两…

【jetson笔记】解决vscode远程调试qt.qpa.xcb: could not connect to display报错

配置x11转发 jetson远程安装x11转发 安装Xming Xming下载 安装完成后打开安装目录C:\Program Files (x86)\Xming 用记事本打开X0.hosts文件&#xff0c;添加jetson IP地址 后续IP改变需要重新修改配置文件 localhost 192.168.107.57打开Xlaunch Win菜单搜索Xlaundch打开 一…

x-cmd pkg | go - Google 开发的开源编程语言

目录 简介首次用户技术特点竞品分析编译型语言解释型语言JavaWebAssebmly 进一步阅读 简介 Go 语言&#xff08;或 Golang&#xff09;是 Google 开发的开源编程语言&#xff0c;诞生于 2006 年。其设计目标是“兼具 Python 等动态语言的开发速度和 C/C 等编译型语言的性能与安…

机器学习---无偏估计

1. 如何理解无偏估计 无偏估计&#xff1a;就是我认为所有样本出现的概率⼀样。 假如有N种样本我们认为所有样本出现概率都是 1/N。然后根据这个来计算数学期望。此时的数学期望就是我们平常讲 的平均值。数学期望本质就 是平均值。 2. 无偏估计为何叫做“无偏”&#xff1…

20240128-读书带来的影响

我本身不算是一个特别喜欢读书的人&#xff0c;更多的时候其实是为了读书而读书。在坚持每天读了一小时书之后&#xff0c;我发现自身开始慢慢有些变化。是什么时候突然有了这种感悟呢&#xff0c;是最近每周5小时左右的微信读书以及纸质书籍的阅读&#xff0c;让我体会到了读书…

常见の算法5

位图 一个int类型32字节&#xff0c;可以表示0-31这32个数出没出现过&#xff0c;出现过1没出现0&#xff0c;再扩大一点搞个数组&#xff0c;就可以表示0-1023出没出现过&#xff0c;一个long类型可储存64位 如何把10位组成的数&#xff0c;第四位由1改成零 package class05…

嵌入式linux面试题目总结

Linux系统中常见的面试题目&#xff0c;分享&#xff0c;欢迎大家前来交流学习。 1、嵌入式系统中的CAN通信协议是什么&#xff1f; CAN&#xff08;Controller Area Network&#xff09;通信协议是一种广泛应用于嵌入式系统中的串行通信协议。它最初由德国汽车工业联合会开发…

VS如何打包环境

以VS2005为例子,做好的软件需要发给客户现场升级,有时候总是因为系统,环境变量不同导致软件不能正常运行打开,这也是程序员非常头疼的问题,今天我们就一起看下打包环境变量. 这样我们的环境变量就打包到setup中了,目标机台安装即可!!!

Java集合-Map接口(key-value)

Map接口的特点&#xff1a;①KV键值对方式存储②Key键唯一&#xff0c;Value允许重复③无序。 Map有四个实现类&#xff1a;1.HashMap类2.LinkedHashMap类3.TreeMap类4.Hashtable类 1.HashMap类&#xff1a; 存储结构&#xff1a;哈希表 数组Node[ ] 链表&#xff08;红黑…