MongoDB 简介
github 地址:https://github.com/mongodb/mongo
官方文档:https://www.mongodb.com/docs/manual/
什么是 MongoDB
MongoDB 是一个开源、高性能、无模式的文档型数据库,主要用于简化开发和方便扩展,是 NoSQL 数据库产品中的一种。是最像关系型数据库(MySQL)的非关系型数据库。
MongoDB 的核心概念是文档,它是一种类似于 JSON 的数据结构叫 BSON,可以包含键值对、数组和嵌套文档。文档以集合的形式组织,类似于关系数据库中的表。每个文档可以有不同的字段和结构,这种灵活性使得 MongoDB 非常适合存储和处理半结构化和多变的数据。
MongoDB 具有很多特点和优势。首先,它具有高性能和可伸缩性,能够处理大规模的数据和高并发访问。其次,它支持丰富的查询语言和索引机制,可以灵活地进行数据检索和分析。此外,MongoDB还提供了复制、分片和故障恢复等功能,以保障数据的可靠性和可用性。
由于 MongoDB 的易用性和强大的功能,它被广泛应用于各种场景,包括 Web 应用程序、实时分析、日志处理、物联网和大数据等领域。它是当今流行的 NoSQL 数据库之一,受到了众多开发者和企业的青睐。
对比 MySQL
MongoDB 和 MySQL 是两种不同类型的数据库管理系统,具有不同的特点和适用场景。
数据模型:MongoDB 是面向文档的非关系型数据库,使用类似 JSON 的 BSON 格式存储数据,支持动态模式。MySQL 是关系型数据库,使用表格和行的结构存储数据,具有固定的模式。
可扩展性:MongoDB 具有较好的可扩展性,支持水平扩展,可以通过分片技术将数据分布到多个节点上,以应对海量数据和高并发访问。MySQL 的扩展性相对较弱,主要通过垂直扩展增加硬件资源来处理更多的数据和请求。
查询语言和灵活性:MongoDB 具有丰富的查询语言和灵活的数据模型,可以进行复杂的数据查询、聚合和分析。MySQL 使用结构化查询语言(SQL)进行查询,较适用于简单的关系型数据查询。
事务支持:MySQL 对事务的支持更加成熟和完善,可以保证数据的一致性和可靠性。MongoDB 在较新的版本中引入了事务支持,但相对 MySQL 来说还不够完善。
存储引擎:MySQL 支持多种存储引擎,如 InnoDB、MyISAM 等,每种存储引擎都有不同的特点和适用场景。MongoDB 使用自己的存储引擎,称为WiredTiger,用于提供高性能和可靠性。
根据具体的应用场景和需求,选择合适的数据库管理系统是很重要的。如果需要处理半结构化数据、需要高可扩展性和灵活性的数据模型,可以选择MongoDB 。如果需要处理严格的关系型数据、需要事务支持和成熟的查询语言,可以选择 MySQL。
MySQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB 不支持 | |
嵌入文档 | MongoDB 通过嵌入式文档来替代多表连接 | |
primary key | primary key | 主键,MongoDB 自动将 _id 字段设置为主键 |
MongoDB 优点
MongoDB 具有以下几个主要优点:
- 灵活的数据模型:MongoDB 是面向文档的数据库,使用类似 JSON 的 BSON 格式存储数据,支持动态模式。这意味着可以存储各种类型和结构的数据,不需要预定义固定的模式。这种灵活性使得 MongoDB 非常适合存储和处理半结构化和多变的数据。
- 高性能和可伸缩性:MongoDB 具有较好的性能和可扩展性。它可以处理大规模的数据和高并发访问,支持水平扩展,可以通过分片技术将数据分布到多个节点上。同时,MongoDB 还使用了索引机制和查询优化技术,以提高查询的性能。
- 丰富的查询语言和功能:MongoDB 提供了丰富的查询语言和功能,可以进行复杂的数据查询、聚合和分析。它支持多种查询操作符和聚合管道,可以灵活地满足各种查询需求。此外,MongoDB 还支持地理空间查询、全文搜索等特殊查询类型。
- 可靠性和可用性:MongoDB 具有复制、故障恢复和自动分片等功能,以保障数据的可靠性和可用性。它支持主从复制和副本集,可以在多个节点之间复制数据,以防止单点故障。同时,当节点发生故障时,MongoDB 可以自动切换到备用节点,以保证服务的连续性。
- 易用性和开发者友好:MongoDB 具有直观的API和易于使用的命令行工具,使得开发者可以快速上手和进行开发工作。它还提供了丰富的驱动程序和集成库,支持多种编程语言和开发框架。此外,MongoDB 还有一个活跃的社区,提供了丰富的文档和资源,方便开发者学习和解决问题。
综上所述,MongoDB 的灵活性、性能、可伸缩性和丰富的功能使其成为处理半结构化数据和大规模数据的理想选择。它被广泛应用于各种场景,包括Web 应用程序、大数据分析、实时数据存储和处理等领域。
业务应用场景
传统的关系型数据库(如 MySQL),在数据操作的“三高”需求以及应对 Web2.0 的网站需求面前,显得力不从心。
解释:“三高”需求:
• High performance
:对数据库高并发读写的需求。
• Huge Storage
:对海量数据的高效率存储和访问的需求。
• High Scalability && High Availability
:对数据库的高可扩展性和高可用性的需求。
而 MongoDB 可应对“三高”需求。
具体的应用场景如:
- 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。
- 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、高效率存储和访问。
- 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
- 物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析。
- 视频直播,使用 MongoDB 存储用户信息、点赞互动信息等。
这些应用场景中,数据操作方面的共同特点是:
- 数据量大
- 写入操作频繁(读写都很频繁)
- 价值较低的数据,对事务性要求不高
对于这样的数据,我们更适合使用MongoDB来实现数据的存储。
什么时候选择 MongoDB
在架构选型上,除了上述的三个特点外,如果你还犹豫是否要选择它?可以考虑以下的一些问题:
应用不需要事务及复杂 join 支持
新应用,需求会变,数据模型无法确定,想快速迭代开发
应用需要2000-3000以上的读写QPS(更高也可以)
应用需要TB甚至 PB 级别数据存储
应用发展迅速,需要能快速水平扩展
应用要求存储的数据不丢失
应用需要99.999%高可用
应用需要大量的地理位置查询、文本查询
如果上述有1个符合,可以考虑 MongoDB,2个及以上的符合,选择 MongoDB 绝不会后悔。
思考:如果用MySQL呢?
答:相对MySQL,可以以更低的成本解决问题(包括学习、开发、运维等成本)
数据模型
MongoDB 的最小存储单位就是文档(document)对象。文档对象对应于关系型数据库的行。数据在 MongoDB 中以 BSON 格式存储在磁盘上。
BSON(Binary Serialized Document Format)是一种类似 JSON 的一种二进制形式的存储格式,简称 Binary JSON。BSON 和 JSON 一样,支持内嵌的文档对象和数组对象,但是 BSON 有 JSON 没有的一些数据类型,如 Date 和 BinData 类型。
BSON 采用了类似于 C 语言结构体的名称、对表示方法,支持内嵌的文档对象和数组对象,具有轻量性、可遍历性、高效性的三个特点,可以有效描述非结构化数据和结构化数据。这种格式的优点是灵活性高,但它的缺点是空间利用率不是很理想。
BSON 中,除了基本的 JSON 类型:string、integer、boolean、double、null、array 和 object,MongoDB 还使用了特殊的数据类型。这些类型包括 date、object id、binary data、regular expression 和 code。每一个驱动都以特定语言的方式实现了这些类型。
BSON 数据类型参考列表:
数据类型 | 描述 | 举例 |
---|---|---|
字符串 | UTF-8 字符串都可表示为字符串类型的数据 | {“x” : “foobar”} |
对象 id | 对象 id 是文档的12字节的唯一 ID | {“X” :ObjectId() } |
布尔值 | 真或者假:true 或者 false | {“x”:true} |
数组 | 值的集合或者列表可以表示成数组 | {“x” : [“a”, “b”, “c”]} |
32位整数 | 类型不可用。JavaScript 仅支持64位浮点数,所以32位整数会被自动转换 | shell 是不支持该类型的,shell 中默认会转换成64位浮点数 |
64位整数 | 类型不可用。shell 会使用一个特殊的内嵌文档来显示64位整数 | shell 是不支持该类型的,shell 中默认会转换成64位浮点数 |
64位浮点数 | shell 中的数字就是这一种类型 | {“x”:3.14159,“y”:3} |
null | 表示空值或者未定义的对象 | {“x”:null} |
undefined | 文档中也可以使用未定义类型 | {“x”:undefined} |
符号 | shell 不支持,shell 会将数据库中的符号类型的数据自动转换成字符串 | |
正则表达式 | 文档中可以包含正则表达式,采用 JavaScript 的正则表达式语法 | {“x” : /foobar/i} |
代码 | 文档中还可以包含 JavaScript 代码 | {“x” : function() { /* …… */ }} |
二进制数据 | 二进制数据可以由任意字节的串组成,不过 shell 中无法使用 | |
最大值/最小值 | BSON 包括一个特殊类型,表示可能的最大值。shell 中没有这个类型 |
shell 默认使用64位浮点型数值。{“x”:3.14} 或 {“x”:3}。对于整型值,可以使用 NumberInt(4字节符号整数)或 NumberLong(8字节符号整数),{“x”:NumberInt(“3”)} {“x”:NumberLong(“3”)}
下载安装
官网下载地址:https://www.mongodb.com/try/download/community
包(package)选择.msi
文件,下载后双击进行安装,之后按照 MongoDB Community Edition 安装向导进行操作
版本的选择:
MongoDB 的版本命名规范如:x.y.z;
y 为奇数时表示当前版本为开发版,如:1.5.2、4.1.13;
**y 为偶数时表示当前版本为稳定版,如:1.6.3、4.0.10;**选择稳定版
z 是修正版本号,数字越大越好。
从 MongoDB 4.0 开始,您可以配置 并在安装过程中将 MongoDB 作为 Windows 服务启动,以及 MongoDB 服务成功后启动 安装。
安装完成后,启动 MongoDB 服务
数据库基本命令
登录到 MongoDB 数据库,默认是没有密码的,默认端口为27017,等价于
mongo --host=127.0.0.1 --port=27017
mongo
C:\Users\DELL>mongo
MongoDB shell version v4.2.19
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("2e16ebf7-6ab7-4da7-a666-a95cb6ae9104") }
MongoDB server version: 4.2.19
Server has startup warnings:
2024-03-09T14:11:13.623+0800 I CONTROL [initandlisten]
2024-03-09T14:11:13.623+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2024-03-09T14:11:13.623+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2024-03-09T14:11:13.623+0800 I CONTROL [initandlisten]
MongoDB Enterprise >
查看已经拥有的数据库
show databases 或 show dbs
MongoDB Enterprise > show databases
admin 0.000GB
config 0.000GB
local 0.000GB
MongoDB Enterprise > show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
退出 MongoDB:
exit
查看 MongoDB 版本
mongo --version
C:\Users\DELL>mongo --version
MongoDB shell version v4.2.19
git version: e68a7d47305e14e090cba9ce3d92533053299996
allocator: tcmalloc
modules: enterprise
build environment:
distmod: windows-64
distarch: x86_64
target_arch: x86_64
更多参数可以通过帮助查看:
mongo -h 或 mongo --help
C:\Users\DELL>mongo --help
MongoDB shell version v4.2.19
usage: mongo [options] [db address] [file names (ending in .js)]
db address can be:
foo foo database on local machine
192.168.0.5/foo foo database on 192.168.0.5 machine
192.168.0.5:9999/foo foo database on 192.168.0.5 machine on port 9999
mongodb://192.168.0.5:9999/foo connection string URI can also be used
Options:
--ipv6 enable IPv6 support (disabled by
default)
--host arg server to connect to
--port arg port to connect to
-h [ --help ] show this usage information
--version show version information
--verbose increase verbosity
--shell run the shell after executing files
--nodb don't connect to mongod on startup - no
'db address' arg expected
--norc will not run the ".mongorc.js" file on
start up
--quiet be less chatty
--eval arg evaluate javascript
--disableJavaScriptJIT disable the Javascript Just In Time
compiler
--enableJavaScriptJIT enable the Javascript Just In Time
compiler
--disableJavaScriptProtection allow automatic JavaScript function
marshalling
--retryWrites automatically retry write operations
upon transient network errors
--disableImplicitSessions do not automatically create and use
implicit sessions
--jsHeapLimitMB arg set the js scope's heap size limit
FLE AWS Options:
--awsAccessKeyId arg AWS Access Key for FLE Amazon KMS
--awsSecretAccessKey arg AWS Secret Key for FLE Amazon KMS
--awsSessionToken arg Optional AWS Session Token ID
--keyVaultNamespace arg database.collection to store encrypted
FLE parameters
--kmsURL arg Test parameter to override the URL for
KMS
Authentication Options:
-u [ --username ] arg username for authentication
-p [ --password ] arg password for authentication
--authenticationDatabase arg user source (defaults to dbname)
--authenticationMechanism arg authentication mechanism
--gssapiServiceName arg (=mongodb) Service name to use when authenticating
using GSSAPI/Kerberos
--gssapiHostName arg Remote host name to use for purpose of
GSSAPI/Kerberos authentication
Kerberos Options:
--sspiHostnamecanonicalization arg (=none)
DNS resolution strategy to use for
hostname canonicalization. May be one
of: {none, forward, forwardAndReverse}
TLS Options:
--tls use TLS for all connections
--tlsCertificateKeyFile arg PEM certificate/key file for TLS
--tlsCertificateKeyFilePassword arg Password for key in PEM file for TLS
--tlsCAFile arg Certificate Authority file for TLS
--tlsCRLFile arg Certificate Revocation List file for
TLS
--tlsAllowInvalidHostnames Allow connections to servers with
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
--tlsDisabledProtocols arg Comma separated list of TLS protocols
to disable [TLS1_0,TLS1_1,TLS1_2]
file names: a list of files to run. files have to end in .js and will exit after unless --shell is specified
常用命令
存放文章评论的数据存放到 MongoDB 中,数据结构参考如下:
数据库名:student
集合名:user
专栏文章评论 | comment | ||
---|---|---|---|
字段名称 | 字段含义 | 字段类型 | |
_id | ID | ObjectId 或 String | Mongo的主键的字段 |
userid | 用户ID | String | |
name | 姓名 | String | |
age | 年龄 | Double | |
sex | 性别 | String |
数据库操作命令
创建及选择数据库
选择到指定数据库,如果数据库不存在则自动创建并切换到这个数据库
use 数据库名称
MongoDB Enterprise > use student
switched to db student
注意:在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。
查看当前正在使用的数据库
db
MongoDB Enterprise > db
student
MongoDB 中默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中。
数据库名可以是满足以下条件的任意UTF-8字符串。
不能是空字符串(“”)。
不得含有’ '(空格)、.、$、/、\和\0 (空字符)。
应全部小写。
最多64字节。
有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
admin
:从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。local
:这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合config
:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
删除数据库
需要先切换到指定的要删除的数据库,再输入以下命令
db.dropDatabase()
MongoDB Enterprise > db.dropDatabase()
{ "ok" : 1 }
提示:主要用来删除已经持久化的数据库
集合操作命令
集合,类似于 mysql 中的表。
可以显示创建(直接使用命令创建),也可以隐式创建,隐式创建就是当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合(常用)。
都是在选择了对应的数据库下进行
创建集合
创建集合(显示创建)
db.createCollection('集合名')
# 单引号或双引号均可
MongoDB Enterprise > db.createCollection('user')
{ "ok" : 1 }
查看数据库中所有集合
show collections 或 show tables
MongoDB Enterprise > show collections
user
MongoDB Enterprise > show tables
user
集合的命名规范:
- 集合名不能是空字符串""。
- 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
- 集合名不能以"system."开头,这是为系统集合保留的前缀。
- 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
删除集合
删除集合,删除成功返回 true,失败返回 false
db.集合名.drop()
MongoDB Enterprise > db.user.drop()
true
MongoDB Enterprise > db.user1.drop()
false
文档操作命令
文档(document)的数据结构和 JSON 基本一样。
所有存储在集合中的数据都是 BSON 格式。
增加数据 insert
单个数据插入
使用
insert()
或save()
方法向集合中插入文档
db.集合名称.insert(
<document or array of documents>,
{
writeConcern: <document>,
ordered: <boolean>
}
)
参数:
document
:要插入到集合中的文档或文档数组。((json格式)writeConcern
:类型为 document,可选参数,参数用于指定写操作的确认方式和持久化要求。它可以在写操作的时候作为选项传递给插入(insert)、更新(update)和删除(delete)等操作,可以包括以下几个选项:- w:指定至少需要在副本集中确认写操作的副本数量。可以是数字,表示确认写操作的副本数,也可以是字符串"majority",表示大多数副本集中的副本。默认值为 1。
- j:表示是否要求写操作被持久化到磁盘。如果设置为 true,则表示写操作需要被持久化到磁盘。默认值为 false。
- wtimeout:表示写操作的超时时间(以毫秒为单位)。如果在指定的时间内没有完成写操作的确认,将抛出异常。默认值为 undefined,表示不设置超时时间。
例如:
writeConcern: { w: 2, j: true, wtimeout: 5000 }
ordered
:类型为 boolean,可选参数,如果为真,则按顺序插入数组中的文档,如果其中一个文档出现错误,MongoDB将返回而不处理数组中的其余文档。如果为假,则执行无序插入,如果其中一个文档出现错误,则继续处理数组中的主文档。在版本2.6+中默认为true
实例:向 comment 的集合中插入一条测试数据:
db.user.insert({userid:"1",name:"zhangsan",age:18,sex:"男"})
MongoDB Enterprise > db.user.insert({userid:"1",name:"zhangsan",age:18,sex:"男"})
WriteResult({ "nInserted" : 1 })
提示:
comment 集合如果不存在,则会隐式创建
MongoDB 中的数字,默认情况下是 double 类型,如果要存整型,必须使用函数 NumberInt(整型数字),否则取出来就有问题了。
插入当前日期使用 new Date()
插入的数据没有指定 _id ,会自动生成主键值
如果某字段没值,可以赋值为null,或不写该字段。
_id 键的组成
自己增加 _id 可以,只需要给插入的 JSON 数据增加 _id 键即可覆盖(但实战强烈不推荐)
注意:
- 文档中的键/值对是有序的。
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
- MongoDB 区分类型和大小写。
- MongoDB 的文档不能有重复的键。
- 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
文档键命名规范:
- 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
- .和$有特别的意义,只有在特定环境下才能使用。
- 以下划线"_"开头的键是保留的(不是严格要求的)。
多条数据插入
db.集合名称.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
db.user.insertMany([
{userid:"2",name:"lisi",age:3,sex:"男"},
{userid:"3",name:"wangwu",age:5,sex:"女"},
{userid:"4",name:"user4",age:9,sex:"男"},
{userid:"5",name:"user5",age:66,sex:"女"}
])
使用for循环插入多条数据
由于mongodb
底层使用JS
引擎实现的,所以支持部分js
语法。因此:可以写for
循环
for (var i = 10; i < 15; i++) {
db.user.insert({
userid:i,
name:"zhangsan"+i,
age:15,
sex:"男"
})
}
如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。
因为批量插入由于数据较多容易出现失败,因此,可以使用 try catch 进行异常捕捉处理,测试的时候可以不处理。
查询文档 find
# 查询多条数据
db.集合名称.find(query, projection)
# 查询满足条件的第一条数据,
db.集合名称.findOne(query, projection)
query
:可选。使用查询运算符指定选择筛选器。若要返回集合中的所有文档,请省略此参数或传递空文档( {} )。projection
:可选。指定要在与查询筛选器匹配的文档中返回的字段(投影)。若要返回匹配文档中的所有字段,请省略此参数。
条件 | 写法 |
---|---|
查询所有的数据 | {}或者不写 |
查询 age=6 的数据 | {age:6} |
既要 age=6 又要性别=男 | {age:6,sex:“男”} |
查询的列(可选参数) | 写法 |
---|---|
查询全部列(字段) | 不写 |
只显示age列(字段) | {age:1} |
除了age列(字段)都显示 | {age:0} |
其他语法:
db.集合名称.find({键:{运算符:值}})
运算符 | 作用 |
---|---|
$gt | 大于 |
$gte | 大于等于 |
$lt | 小于 |
$lte | 小于等于 |
$ne | 不等于 |
$in | in |
$nin | not in |
练习
- 查询
age
大于10
的数据
db.user.find({age:{$gt:10}})
- 查询年龄是
3
岁、4
岁、5
岁的数据,只看年龄列
db.user.find({age:{$in:[2,4,5]}},{age:1})
这里你会发现每条文档会有一个叫 _id 的字段,这个相当于我们原来关系数据库中表的主键,当你在插入文档记录时没有指定该字段,MongoDB 会自动创建,其类型是 ObjectID 类型。
如果不想显示 _id 字段,只需加上 _id:0
即可
db.user.find({age:{$in:[2,4,5]}},{age:1,_id:0})
- 只看年龄列,或者年龄以外的列
# 只看年龄列
db.user.find({},{age:1})
# 只看年龄以外的列
db.user.find({},{age:0})
更新文档 update
db.集合名称.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2
}
)
主要关注前4个参数:
query
:更新的选择条件,也就是你要更新的数据的查询条件,类似于 mysql 中 where 后的语句update
:更新后的数据,类似于 mysql 中 update set 后的语句upsert
:可选。如果设置为 true,则在没有与查询条件匹配的文档时创建新文档。默认值为 false,如果找不到匹配项,则不会插入新文档。multi
:可选。如果设置为 true,则更新符合查询条件的多个文档。如果设置为 false,则更新一个文档。默认值为 false。
示例:
- 覆盖修改,更新后的数据会覆盖掉原来的数据
db.user.update({userid:"1"}, {name:"lisi"})
可以看到,修改后的数据只保留了 name 字段,其余字段全被覆盖掉
- 局部修改,更新后的数据不会覆盖掉原来的数据
为了避免覆盖,需要使用修改器 $set 来实现
db.user.update({userid:"2"}, {$set:{name:"zhangsan"}})
可以看到,只有 name 字段的值进行了修改
- 批量修改
update()
方法默认只修改符合条件的第一条数据,如果想要批量修改数据,则需要加上multi: true
db.user.update({age:15}, {$set:{name:"lisi"}},{multi:true})
或者使用updateMany()
方法
db.user.updateMany({age:15}, {$set:{name:"zhangsan"}})
- 列值增加
如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用 $inc 运算符来实现。
db.user.update({userid:10}, {$inc:{age:1}})
删除文档 delete
# 删除一条数据
db.集合名称.deleteOne(filter, options)
# 删除多条数据
db.集合名称.deleteMany(filter, options)
- 删除一条数据
db.user.deleteOne({name:"zhangsan"})
- 删除多条数据
db.user.deleteMany({name:"zhangsan"})
不带条件时:
# 删除集合中第一条数据
db.user.deleteOne({})
# 删除集合所有数据,慎用,删库跑路
db.user.deleteMany({})
分页查询
清空集合中所有数据,重新添加20条数据
for (var i = 1; i <= 20; i++) {
db.user.insert({
userid:i,
name:"zhangsan"+i,
age:i,
sex:"男"
})
}
统计查询
查询集合中数据数量
db.集合名称.count(query, options)
db.user.count() # 查询集合中数据总数
db.user.count({userid:5}) # 查询集合中 userid 为5的数据个数
分页查询
可以使用limit()
方法来读取指定数量的数据,使用skip()
方法来跳过指定数量的数据。
db.集合名称.find().limit(<number>).skip(offset)
示例:查询前5条数据
db.user.find().limit(5)
查询 6-10 条数据
db.user.find().limit(5).skip(5)
排序查询
sort()
方法对数据进行排序, 1 为升序排列, -1 为降序排列。
根据 userid 降序查询前5条数据
db.user.find().limit(5).sort({userid:-1})
skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit(),和命令编写顺序无关。
常用命令小结
选择切换数据库:use 数据库名
插入数据:db.集合名.insert({})
查询所有数据:db.集合名.find();
条件查询数据:db.集合名.find({条件})
查询符合条件的第一条记录:db.集合名.findOne({条件})
查询符合条件的前几条记录:db.集合名.find({条件}).limit(条数)
查询符合条件的跳过的记录:db.集合名.find({条件}).skip(条数)
修改数据:db.集合名.update({条件},{修改后的数据}) 或 db.集合名.update({条件},{$set:{要修改部分的字段:数据})
修改数据并自增某字段值:db.集合名.update({条件},{$inc:{自增的字段:步进值}})
删除数据:db.集合名.delete({条件})
统计查询:db.集合名.count({条件})
模糊查询:db.集合名.find({字段名:/正则表达式/})
条件比较运算:db.集合名.find({字段名:{$gt:值}})
包含查询:db.集合名.find({字段名:{$in:[值1,值2]}}) 或 db.集合名.find({字段名:{$nin:[值1,值2]}})
条件连接查询:db.集合名.find({$and:[{条件1},{条件2}]}) 或 db.集合名.find({$or:[{条件1},{条件2}]})
索引 index
什么是索引
索引支持在 MongoDB 中高效地执行查询。如果没有索引,MongoDB 必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
如果查询存在适当的索引,MongoDB 可以使用该索引限制必须检查的文档数。
索引是特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB 还可以使用索引中的排序返回排序结果。
MongoDB 索引使用B树数据结构(确切的说是 B-Tree,MySQL是 B+Tree)
索引类型
单字段索引
MongoDB 支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index)。
对于单个字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为 MongoDB 可以在任何方向上遍历索引。
复合索引
MongoDB 还支持多个字段的用户定义索引,即复合索引(Compound Index)。
复合索引中列出的字段顺序具有重要意义。例如,如果复合索引由 { userid: 1, score: -1 } 组成,则索引首先按 userid 正序排序,然后
在每个 userid 的值内,再在按 score 倒序排序。
其它索引
- 地理空间索引(Geospatial Index):为了支持对地理空间坐标数据的有效查询,MongoDB 提供了两种特殊的索引:返回结果时使用平面几何的二维索引和返回结果时使用球面几何的二维球面索引。
- 文本索引(Text Indexes):MongoDB 提供了一种文本索引类型,支持在集合中搜索字符串内容。这些文本索引不存储特定于语言的停止词(例如“the”、“a”、“or”),而将集合中的词作为词干,只存储根词。
- 哈希索引(Hashed Indexes):为了支持基于散列的分片,MongoDB 提供了散列索引类型,它对字段值的散列进行索引。这些索引在其范围内的值分布更加随机,但只支持相等匹配,不支持基于范围的查询。
索引操作命令
查看索引
返回集合中的所有索引
db.集合名称.getIndexes()
提示:该语法命令运行要求是MongoDB 3.0+
MongoDB Enterprise > db.user.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "student.user"
}
]
默认 _id 索引:
MongoDB 在创建集合的过程中,在 _id 字段上创建一个唯一的索引,默认名字为 _id ,该索引可防止客户端插入两个具有相同值的文档,您不能在 _id字段上删除此索引。
注意:该索引是唯一索引,因此值不能重复,即 _id 值不能重复的。在分片集群中,通常使用 _id 作为片键。
创建索引
db.集合名称.createIndex(keys, options)
注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex()
,之后的版本使用了 db.collection.createIndex()
方法,ensureIndex()
还能用,但只是 createIndex()
的别名。
删除索引
删除指定索引:
db.集合名称.dropIndex(index)
删除所有索引:
db.user.dropIndexes()
提示: _id 的字段的索引是无法删除的,只能删除非 _id 字段的索引。