文章目录
基础原理
MongoDB是什么
MongoDB是一种专门用于应用程序开发和扩展的文档数据库。该数据库以文档的形式(BSON文档)存储数据记录,这些文档被聚集在集合中,并且一个数据库可以存储一个或多个文档集合。
与传统关系型数据库不同的是,MongoDB采用BSON文档格式来存储数据记录。BSON是一种二进制表示的JSON文档,其中包含零个或多个有序的键值对,这些键值对作为单个实体存储在MongoDB中。因此,MongoDB的数据存储结构非常灵活,可以存储各种类型和格式的数据。
MongoDB不仅用于存储文档数据,还可以用于进行远程过程调用。通过MongoDB,应用程序可以轻松地存储和访问数据,并且可以方便地进行分布式数据处理和扩展。这使得MongoDB成为了现代应用程序开发中不可或缺的一部分。
现状和前景
MongoDB在数据库总排名中位列第五,仅次于诸如Oracle和MySQL等关系型数据库管理系统(RDBMS)。但是,在NoSQL数据库中,MongoDB排名第一。自从MongoDB诞生以来,它的应用广度和社区活跃指数持续上升。
这主要得益于MongoDB作为一种灵活的、可扩展的NoSQL数据库,在处理大规模数据时表现出色。除此之外,MongoDB还具有易于学习和使用、支持数据的动态查询和索引、高可用性和强大的复制特性等诸多优点,使得越来越多的开发人员和组织选择MongoDB作为其首选的数据库解决方案。
总之,MongoDB的在NoSQL数据库领域中的领先地位和持续增长的应用范围,为它在数据库市场中赢得了广泛的认可和推崇。
对比mysql
MongoDB 是一种文档数据库,而 MySQL 是一种关系型数据库。它们有许多概念和术语是不同的,以下是一些常见的对比:
MongoDB | MySQL |
---|---|
文档(Document) | 行(Row) |
集合(Collection) | 表(Table) |
字段(Field) | 列(Column) |
数据库(Database) | 数据库(Database) |
主键(Primary key) | 主键(Primary key) |
二级索引(Secondary index) | 索引(Index) |
聚合(Aggregation) | 聚合函数(Aggregate function) |
复制集(Replica set) | 主从复制(Master-slave replication) |
分片(Sharding) | 分区(Partitioning) |
需要注意的是,MongoDB 和 MySQL 在某些概念和术语上存在差异,但它们都是用于存储和管理数据的数据库系统,具有相似的功能和用途。具体选择哪个数据库系统,应该根据具体的需求和场景进行选择。
基础语法
下面会详细的介绍常用的语法,并结合详细的例子说明。关于mongodb在linxu和windows的安装,请参考该文章。
软件版本
mongodb服务端的版本:6.0.5
mongodb客户端的版本:1.8.2
系统版本:7.6.1810
数据风格
前面提到了,mongodb是一个文档形式的数据库,其直接表现形式就是我们场景的json风格,一行文档数据就是一个经典的键值对形式,并且支持内嵌文档,如
{
_id: ObjectId("5099803df3f4948bd2f98391"),
name: { first: "Alan", last: "Turing" },
birth: new Date('Jun 23, 1912'),
death: new Date('Jun 07, 1954'),
contribs: [ "Turing machine", "Turing test", "Turingery" ],
views : NumberLong(1250000)
}
字段解释
_id: 该文档的唯一主键
name: 保存包含字段first和last的嵌入式文档。
birth 和death: 保存日期格式的值
contribs: 保存一个字符串数组
views: 保存NumberLong类型的值
字段名
在MongoDB中,字段名称是用字符串格式定义的。MongoDB对字段名有以下限制:
-
_id是保留字段,通常被用作主键。它的值必须在集合中是唯一的,且不能被修改,可以是任何类型,但不能是数组。如果_id包含子字段,则子字段的名称不能以美元符号($)开头。
-
字段名不能包含空字符。
-
服务器允许存储包含点(.)和美元符号($)的字段名。但需要注意,在字段名称中使用特殊字符可能会对查询和操作产生影响,因此需要格外小心。
-
MongoDB 5.0版本开始增加了对字段名称中美元符号($)和点(.)的使用支持,但仍有一些限制。具体的信息可以参考MongoDB文档中的“字段名称注意事项”部分。
总之,字段名称在MongoDB中相对灵活,但需要遵守一些规范和限制,以保证数据的正确性和查询效率。
点符号
在MongoDB中,点符号(.)用于访问数组的元素和嵌入式文档的字段。下面是一些关于点符号的使用规则和示例:
- 访问数组元素:
要访问数组中的元素,请将数组名称与点号和基于零的索引位置连接起来,并用引号括起来。例如,要访问名为contribs的数组中的第三个元素,请使用“contribs.2”。如下所示:
{
...
contribs: [ "Turing machine", "Turing test", "Turingery" ],
...
}
- 访问嵌入式文档的字段:
要访问嵌入式文档中的字段,请将文档名称与点号和字段名称连接起来,并用引号括起来。例如,要访问嵌入式文档中的字段“street”,请使用“address.street”。如下所示:
{
...
address: {
street: "123 Main St",
city: "Anytown",
state: "CA"
},
...
}
总之,MongoDB使用点符号访问数组元素和嵌入式文档的字段。使用这些规则可以方便地访问和操作MongoDB中的数据。
用户管理
在 MongoDB 中,用户可以创建数据库并设置访问权限,以控制不同用户对数据库的操作。
常用的命令
- 查看当前数据库的用户:show users
- 查看当前数据库支持的角色列表:show roles
- 为当前数据库创建用户(如果需要创建管理员如root绝对的需要切换到admin数据库在操作):db.createUser({user:“{用户名称}”,pwd:“{密码}”,roles:[“{角色名称}”]})
- 查询角色的具体用途:db.getRole(“{角色名称}”,{showPrivileges: true})
用户自建数据库支持的角色
角色是一种权限设置机制,用于控制用户对数据库资源的操作。MongoDB 中内置了多种角色,可以根据需要进行分配。
以下是用户数据库可中内置的角色及其说明:
- read:可以对指定数据库中的集合执行读操作,但不能执行写操作。
- readWrite:可以对指定数据库中的集合执行读和写操作。
- dbAdmin:可以执行数据库的管理任务,如备份和恢复、创建和删除集合等。
- userAdmin:可以管理数据库用户,包括创建、删除和修改用户的权限。
- dbOwner:可以执行数据库的所有操作,相当于该数据库的超级管理员。
- enableSharding:可以执行启动当前数据库的分片。
下面是admin数据库内置的角色(包括上面的)
- clusterAdmin:可以执行 MongoDB 集群的管理操作,包括添加和删除节点、管理副本集等。
- backup:可以执行 MongoDB 数据库的备份操作。
- restore:可以执行 MongoDB 数据库的恢复操作。
- root:可以执行任何操作,相当于整个 MongoDB 实例的超级管理员。
- readAnyDatabase:可以读取 MongoDB 实例上的任何数据库。
- readWriteAnyDatabase:可以读写 MongoDB 实例上的任何数据库。
- userAdminAnyDatabase:可以在 MongoDB 实例上管理任何数据库的用户。
- dbAdminAnyDatabase:可以在 MongoDB 实例上执行任何数据库的管理任务。
- backupAnyDatabase:可以在 MongoDB 实例上备份任何数据库。
- restoreAnyDatabase:可以在 MongoDB 实例上恢复任何数据库。
superuser:可以执行任何操作,相当于整个 MongoDB 实例的超级管理员。
这些角色可以通过 MongoDB 的访问控制机制来进行管理和分配。通过分配不同的角色,用户可以实现对数据库资源的不同权限控制。
注意:每个版本的角色有所不同,可以使用查询角色列表命令显示当前版本的角色
例子
1.创建超管用户 root,密码是123456
#超管用户需要切换到admin
test> use admin
switched to db admin
admin> db.createUser({user:"root",pwd:"123456",roles:["read"]})
{ ok: 1 }
mydb>
管理员在使用shell登陆时
./mongosh -u root -p 123456 --authenticationDatabase admin
2.给数据库mydb创建只读的用户 test,密码是123456
admin> use mydb
switched to db mydb
# test表插入一行记录
mydb> db.test.insertOne({name:"aaa"})
{
acknowledged: true,
insertedId: ObjectId("645f8fae6b85b10ef9c36a27")
}
mydb> db.createUser({user:"test",pwd:"123456",roles:["read"]})
{ ok: 1 }
mydb> show users
[
{
_id: 'mydb.test',
userId: new UUID("b690ade4-fb54-46de-b83a-867c6fb140e4"),
user: 'test',
db: 'mydb',
roles: [ { role: 'read', db: 'mydb' } ],
mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
}
]
登陆时,需要输入
./mongosh -u test -p 123456 --authenticationDatabase mydb
test用户不能写入数据
test> use mydb
switched to db mydb
mydb> db.test.find()
[ { _id: ObjectId("645f8fae6b85b10ef9c36a27"), name: 'aaa' } ]
mydb> db.test.insertOne({name:"bbb"})
MongoServerError: not authorized on mydb to execute command { insert: "test", documents: [ { name: "bbb", _id: ObjectId('645f9183ecb44476284237c4') } ], ordered: true, lsid: { id: UUID("50c0ab81-50d7-4aff-b392-662ddaea7923") }, $db: "mydb" }
mydb>
登陆超管账号修改test的权限为可以读写
test> use mydb
switched to db mydb
# 修改前查询用户的角色
mydb> show users
[
{
_id: 'mydb.test',
userId: new UUID("b690ade4-fb54-46de-b83a-867c6fb140e4"),
user: 'test',
db: 'mydb',
roles: [ { role: 'read', db: 'mydb' } ],
mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
}
]
# 修改角色
mydb> db.updateUser("test",{roles:["readWrite"]})
{ ok: 1 }
# 修改后查询
mydb> show users
[
{
_id: 'mydb.test',
userId: new UUID("b690ade4-fb54-46de-b83a-867c6fb140e4"),
user: 'test',
db: 'mydb',
roles: [ { role: 'readWrite', db: 'mydb' } ],
mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
}
]
修改完角色后会立马生效,回到test登陆的客户端可以执行插入数据
mydb> db.test.insertOne({name:"bbb"})
{
acknowledged: true,
insertedId: ObjectId("645f92e0ecb44476284237c5")
}
mydb> db.test.find()
[
{ _id: ObjectId("645f8fae6b85b10ef9c36a27"), name: 'aaa' },
{ _id: ObjectId("645f92e0ecb44476284237c5"), name: 'bbb' }
]
数据库操作
常用的数据库操作命令
- 查询数据库列表: show dbs
- 切换到要使用的数据库,没有则创建 :use {数据库名称}
- 删除当前数据库:db.dropDatabase()
使用例子
# 查询数据库列表
test> show dbs;
admin 40.00 KiB
config 60.00 KiB
local 72.00 KiB
# 切换到要使用的数据库,没有则创建
test> use mydb
switched to db mydb
# 删除当前数据库
mydb> db.dropDatabase()
{ ok: 1, dropped: 'mydb' }
# 再次查询发现已经删除
mydb> show dbs
admin 40.00 KiB
config 60.00 KiB
local 72.00 KiB
mydb>
集合操作
集合的概念以及注意事项
MongoDB 中集合(Collection)是存储文档(Document)的容器,类似于关系数据库中的表(Table),但是 MongoDB 中的集合更加灵活,没有固定的结构,不需要定义表头(Schema),可以在一个集合中存储不同结构的文档。
以下是 MongoDB 集合的一些注意事项:
- 集合名称必须是唯一的,不允许出现重复的名称。
- 集合名称不能包含 MongoDB 保留的字符,例如 $ 和 . 等。
- 如果在插入文档时指定的集合不存在,MongoDB 会自动创建该集合。
- 由于 MongoDB 的集合没有固定的结构,因此需要应用程序保证不同文档之间的结构一致性。
- 在进行查询和聚合操作时,需要注意不同文档之间的字段可能存在差异,需要进行合适的处理。
- 在使用 MongoDB 分片集群时,集合的 shard key 需要根据实际情况进行选择,避免数据倾斜和热点问题。
- 集合中的数据可以根据业务需要进行分片,以提高性能和扩展性。
MongoDB 集合的灵活性和动态性使得它在处理非结构化和半结构化数据方面非常适合,但是需要应用程序保证文档之间的结构一致性和数据的完整性。
集合的创建方式
MongoDB 中集合(Collection)有两种创建方式:
- 隐式创建
- 显示创建
隐式创建
隐式创建是指在插入文档时,如果指定的集合不存在,MongoDB 会自动创建该集合。例如,以下代码将会自动创建名为的集合,并插入一个文档:
db.user.insertOne({name: "John", age: 30})
如果 user集合不存在,MongoDB 会自动创建该集合,并将文档插入到该集合中。
显示创建
显示创建是指通过 db.createCollection() 方法显示地创建集合。该方法有两个参数,第一个参数是集合名称,第二个参数是一个可选的选项对象,用于指定集合的一些属性,例如集合的存储引擎、文档的验证规则等。例如,以下代码显示地创建了一个名为 user的集合:
db.createCollection("user", {capped: true, size: 100000})
以上代码创建了一个固定大小的集合(capped collection),最大容量为 100000 字节。
需要注意的是,MongoDB 的隐式创建和显示创建都是在当前数据库中创建集合,而不是在集群中创建。如果在分片集群中创建集合,需要使用 sh.shardCollection() 方法来将集合分片。
在 MongoDB 中,创建集合时可以使用一些选项来配置集合的属性,以下是常见的选项:
- capped:指定集合是否是固定大小的,即固定容量的集合。默认值为 false。
- size:指定固定大小集合的大小(以字节为单位)。该选项仅在 capped 为 true 时才有效。
- max:指定固定大小集合可以包含的最大文档数。该选项仅在 capped 为 true 时才有效。
- storageEngine:指定集合的存储引擎。默认为 MongoDB 的默认存储引擎 WiredTiger。
- validator:指定集合中文档的验证规则。该选项允许定义集合中文档的结构和数据类型等限制条件。
- validationLevel:指定文档验证的级别。有 strict 和 moderate 两种级别可选,默认为 strict。
- validationAction:指定验证失败时的行为。有 error 和 warn 两种行为可选,默认为 error。
- indexOptionDefaults:指定集合中所有索引的默认选项。例如,可以指定索引的默认过期时间、默认的排序顺序等。
注意:不是所有选项都在所有版本的 MongoDB 中都可用,而且有些选项只能在特定的存储引擎中使用。因此,在使用这些选项时需要仔细查阅 MongoDB 的官方文档并确认其可用性和兼容性。
文档操作
在 MongoDB 中,文档(Document)是最基本的数据存储单元,它类似于关系型数据库中的行(row)。文档是由键值对(key-value pairs)构成的,每个键(key)是一个字符串,对应一个值(value),值可以是字符串、数字、日期、数组、嵌套文档等类型。
插入文档
在 MongoDB 中,可以使用以下方法向文档中插入数据:
- insertOne( 数据, 可选参数 }:向集合中插入一条文档。
- insertMany( 数据, 可选参数 ):向集合中插入多条文档。
- bulkWrite():执行多个写入操作,并控制执行顺序。
以下是常用的插入文档时可选参数:
- writeConcern:指定写入操作的安全级别。例如,可以使用 {w: 1} 来指定写入操作需要在主节点上完成,并等待确认。
- ordered:指定插入文档的顺序。默认情况下,MongoDB 会按照插入文档的顺序进行插入,如果某个文档插入失败,则会中断后续文档的插入操作。可以使用 {ordered: false} 来指定不按照顺序插入文档。
- bypassDocumentValidation:指定是否跳过文档验证。默认情况下,MongoDB 会在插入文档时对文档进行验证,以确保文档结构符合集合的架构。可以使用 {bypassDocumentValidation: true} 来跳过验证。
- collation:指定文档的排序规则。例如,可以使用 {collation: {locale: “en_US”, strength: 2}} 来指定按照英语的字典顺序进行排序。
- session:指定操作所属的会话对象。如果需要在事务中进行插入操作,则需要将插入操作与会话对象关联起来。
使用例子
- 例子1:新增单个文档
mydb> db.user.insertOne({name:"jerry",age:18})
{
acknowledged: true,
insertedId: ObjectId("6460601650a6da7511b2d277")
}
- 例子2:新增多个文档
mydb> db.user.insertMany([{name:"tom",age:21},{name:"xiaoming",age:15},{name:"lili",age:17}])
{
acknowledged: true,
insertedIds: {
'0': ObjectId("6460605d50a6da7511b2d278"),
'1': ObjectId("6460605d50a6da7511b2d279"),
'2': ObjectId("6460605d50a6da7511b2d27a")
}
}
注意:在新版本中,使用insert()方法插入数据时虽然会成功但会提示弃用警告,建议使用其他方法
mydb> db.user.insert({name:"tom"})
DeprecationWarning: Collection.insert() is deprecated. Use insertOne, insertMany, or bulkWrite.
{
acknowledged: true,
insertedIds: { '0': ObjectId("64605d6e50a6da7511b2d274") }
}
mydb>
- 使用加载js文件的方式插入数据
下面是user.js的脚本,和客户端放在同一个目录下
var users = [];
for(var i=1;i<=10;i++){
var u = {};
u.name="user-"+i;
u.age=10+i;
users.push(u);
}
db.user.insertMany(users);
执行加载js文件
mydb> load("user.js")
true
mydb> db.user.find()
[
...
{
_id: ObjectId("646061e050a6da7511b2d27b"),
name: 'user-1',
age: 11
},
{
_id: ObjectId("646061e050a6da7511b2d27c"),
name: 'user-2',
age: 12
},
{
_id: ObjectId("646061e050a6da7511b2d27d"),
name: 'user-3',
age: 13
},
...
]
js内容也可以直接在客户端执行
查询文档
find()
方法是 MongoDB 中用于查询集合中文档的最基本的方法之一。该方法可以接受一个或多个参数,用于指定查询条件、投影和排序等信息。以下是 find() 方法的详细介绍:
基本语法
db.collection.find(query, projection)
- query:可选参数,用于指定查询条件。可以使用查询运算符和逻辑运算符来组合多个条件。
- projection:可选参数,用于指定投影条件。可以使用投影运算符来指定需要返回的字段或排除的字段。
查询条件
如果直接使用find()
会返回所有的数据,在数据量大的情况下是很糟糕的一件事,会增加响应时间和占用资源,应该增加一些查询条件。
可以使用各种运算符来指定查询条件,例如:
- 等于运算符:{ field: value }
- 不等于运算符:{ field: { $ne: value } }
- 大于运算符:{ field: { $gt: value } }
- 小于运算符:{ field: { $lt: value } }
- 大于等于运算符:{ field: { $gte: value } }
- 小于等于运算符:{ field: { $lte: value } }
- 正则表达式运算符:{ field: /pattern/ }
- 数组运算符:{ field: { $in: [value1, value2, …] } }
- 逻辑运算符:{ $or: [ { field1: value1 }, { field2: value2 }, … ] }
- 可以使用多个运算符来组合多个查询条件,例如:
例子:
user表所有的数据
mydb> db.user.find()
[
{ _id: ObjectId("6460637e50a6da7511b2d2a3"), name: 'jerry', age: 18 },
{ _id: ObjectId("6460638150a6da7511b2d2a4"), name: 'tom', age: 21 },
{
_id: ObjectId("6460638150a6da7511b2d2a5"),
name: 'xiaoming',
age: 15
},
{ _id: ObjectId("6460638150a6da7511b2d2a6"), name: 'lili', age: 17 }
]
查询age小于等于15的数据
mydb> db.user.find({age:{$lte:15}})
[
{
_id: ObjectId("6460638150a6da7511b2d2a5"),
name: 'xiaoming',
age: 15
}
]
投影条件
投影条件用于指定需要返回的字段或排除的字段。可以使用投影运算符 $project 来指定需要返回的字段,使用投影运算符 $exclude 来指定需要排除的字段。例如:
db.collection.find({}, { field1: 1, field2: 1, _id: 0 })
上述语句将返回所有文档的 field1 和 field2 字段,但排除了 _id 字段。
例子:
返回user表中所有的数据,但只返回name字段
mydb> db.user.find({},{_id:0,name:1})
[
{ name: 'jerry' },
{ name: 'tom' },
{ name: 'xiaoming' },
{ name: 'lili' }
]
排序条件
排序条件用于指定返回的文档按照哪个字段排序。可以使用 sort() 方法来指定排序条件,例如:
db.collection.find().sort({ field1: 1 })
上述语句将返回所有文档,并按照 field1 字段升序排列。
其他选项
find() 方法还支持其他选项,例如:
- limit():限制返回的文档数量。
- skip():指定要跳过的文档数量。
- count():返回满足查询条件的文档数量。
以上是 find() 方法的一些常用选项和语法,实际使用中可以根据需求灵活使用。
使用例子
多插入几行数据
db.user.insertMany([{name:"liming",age:18},{name:"lisa",age:17},{name:"dave",age:7},{name:"laose",age:27},{name:"make",age:14},{name:"selltye",age:22},{name:"gim",age:19}])
查询user表中所有的数量
mydb> db.user.find().count()
11
查询年龄大于15并且只返回name字段
mydb> db.user.find({age:{$gte:15}},{_id:0,name:1})
[
{ name: 'jerry' },
{ name: 'tom' },
{ name: 'xiaoming' },
{ name: 'lili' },
{ name: 'liming' },
{ name: 'lisa' },
{ name: 'laose' },
{ name: 'selltye' },
{ name: 'gim' }
]
只返回前2条
mydb> db.user.find({age:{$gte:15}},{_id:0,name:1}).limit(2)
[ { name: 'jerry' }, { name: 'tom' } ]
只返回前第3-第4条
mydb> db.user.find({age:{$gte:15}},{_id:0,name:1}).skip(2).limit(2)
[ { name: 'xiaoming' }, { name: 'lili' } ]
查询年龄大于15,同时将name修改成user_name,并且按照年龄从大到小排序返回
mydb> db.user.find({age:{$gte:15}},{_id:0,user_name:"$name",age:1}).sort({age:-1})
[
{ age: 27, user_name: 'laose' },
{ age: 22, user_name: 'selltye' },
{ age: 21, user_name: 'tom' },
{ age: 19, user_name: 'gim' },
{ age: 18, user_name: 'jerry' },
{ age: 18, user_name: 'liming' },
{ age: 17, user_name: 'lili' },
{ age: 17, user_name: 'lisa' },
{ age: 15, user_name: 'xiaoming' }
]
更新文档
在 MongoDB 中,可以使用 updateOne
和updateMany
方法来更新文档。方法接收三个参数,第一个参数是一个查询条件,用于指定需要更新的文档;第二个参数是一个更新操作,用于指定需要进行的更新操作;第三个参数是可选的配置参数。
MongoDB提供了以下方法来更新集合中的文档:
- db.collection.updateOne (过滤条件,更新操作,配置参数):即使多个文档可能与指定的筛选器匹配,也只会更新第一个匹配的文档。
- db.collection.updateMany (过滤条件,更新操作,配置参数):更新与指定筛选器匹配的所有文档。
注意:在 MongoDB 4.2 及以上版本中,update
方法已经被废弃
内置的更新参数
更新文档时可以使用一些内置的参数,这些参数可以控制更新操作的行为。以下是常用的一些内置的更新参数:
- upsert:如果查询条件匹配的文档不存在,则创建一个新的文档。
- multi:将匹配到的所有文档都更新,默认只会更新第一条匹配的文档。
- returnNewDocument:在更新操作完成后,返回更新后的文档而不是更新前的文档。
- writeConcern:用于控制更新操作的写入安全级别。
- collation:用于指定文本比较的规则,例如大小写敏感性、重音符号等。
- arrayFilters:用于指定更新操作的过滤条件,仅当更新操作对象中的数组满足指定条件时才进行更新操作。
内置的操作符
以下是常用的一些内置的更新操作符:
- $set:设置文档中指定字段的值,如果指定的字段不存在,则会创建该字段。
- $unset:从文档中删除指定的字段。
- $inc:将文档中指定字段的值增加指定的值,如果指定的字段不存在,则会创建该字段。
- $mul:将文档中指定字段的值乘以指定的值,如果指定的字段不存在,则会创建该字段。
- $rename:将文档中指定字段重命名为指定的字段名。
- $push:向文档中指定的数组字段中添加一个值。
- $pushAll:向文档中指定的数组字段中添加多个值。
- $pull:从文档中指定的数组字段中删除一个值。
- $pullAll:从文档中指定的数组字段中删除多个值。
- $addToSet:添加元素到数组中,内置去重。
- $pop:从文档中指定的数组字段中删除第一个或最后一个元素。
- $bit:对文档中指定的整数字段执行位运算操作。
这些更新操作符可以通过 $ 符号的形式,加在更新操作对象中,以指定需要进行的操作。
使用例子
- 将name等于laose的用户年龄增加1
mydb> db.user.find({name:"laose"})
[
{ _id: ObjectId("6460674850a6da7511b2d2aa"), name: 'laose', age: 28 }
]
mydb> db.user.updateOne({name:"laose"},{$inc:{age:1}})
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
mydb> db.user.find({name:"laose"})
[
{ _id: ObjectId("6460674850a6da7511b2d2aa"), name: 'laose', age: 29 }
]
- 给name等于tom的用户添加数组字段tag
mydb> db.user.find({name:"tom"})
[ { _id: ObjectId("6460638150a6da7511b2d2a4"), name: 'tom', age: 21 } ]
mydb> db.user.updateOne({name:"tom"},{$set:{tag:["a","b"]}})
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
mydb> db.user.find({name:"tom"})
[
{
_id: ObjectId("6460638150a6da7511b2d2a4"),
name: 'tom',
age: 21,
tag: [ 'a', 'b' ]
}
]
- 给name等于tom的用户,把”c“添加数组字段tag中
mydb> db.user.updateOne({name:"tom"},{$push:{tag:"c"}})
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
mydb> db.user.find({name:"tom"})
[
{
_id: ObjectId("6460638150a6da7511b2d2a4"),
name: 'tom',
age: 21,
tag: [ 'a', 'b', 'c' ]
}
]
- 删除name等于tom的用户的tag字段
mydb> db.user.updateOne({name:"tom"},{$unset:{tag:""}})
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
mydb> db.user.find({name:"tom"})
[ { _id: ObjectId("6460638150a6da7511b2d2a4"), name: 'tom', age: 21 } ]
mydb>
删除文档
语法
在 MongoDB 中,删除文档可以使用remove()
或 deleteOne()
或 deleteMany()
方法。
- db.collection.remove(查询条件,可选参数):如果查询条件为空对象 {},则表示删除集合中的所有文档。
- db.collection.deleteOne(查询条件):删除匹配到的一行数据,等同remove()方法的justOne可选参数设置为true
- db.collection.deleteMany(查询条件):删除匹配到数据
- db.collection.findOneAndDelete(查询条件):返回匹配到的一行数据并将其删除,上面的deteleOne()只会返回删除的结果
- db.collection.drop():删除整个表的数据,等同于deleteMany({}),但比deleteMany要高效,因为deleteMany要编译后才删除,而drop()则直接删除
使用例子
- 删除name等于tom的数据
mydb> db.user.find({name:"tom"})
[ { _id: ObjectId("6460638150a6da7511b2d2a4"), name: 'tom', age: 21 } ]
mydb> db.user.deleteOne({name:"tom"})
{ acknowledged: true, deletedCount: 1 }
mydb> db.user.find({name:"tom"})
mydb>
- 删除age等于17的所有数据
mydb> db.user.find({age:17})
[
{ _id: ObjectId("6460638150a6da7511b2d2a6"), name: 'lili', age: 17 },
{ _id: ObjectId("6460674850a6da7511b2d2a8"), name: 'lisa', age: 17 }
]
mydb> db.user.deleteMany({age:17})
{ acknowledged: true, deletedCount: 2 }
mydb> db.user.find({age:17})
mydb>
- 返回name等于dave的数据并删除
mydb> db.user.find({name:"dave"})
[ { _id: ObjectId("6460674850a6da7511b2d2a9"), name: 'dave', age: 7 } ]
mydb> db.user.findOneAndDelete({name:"dave"})
{ _id: ObjectId("6460674850a6da7511b2d2a9"), name: 'dave', age: 7 }
mydb> db.user.find({name:"dave"})
mydb>
- 删除整个user表,推荐使用drop()方法,更加高效
mydb> db.user.find()
[
{ _id: ObjectId("6460637e50a6da7511b2d2a3"), name: 'jerry', age: 18 },
{
_id: ObjectId("6460638150a6da7511b2d2a5"),
name: 'xiaoming',
age: 15
},
{
_id: ObjectId("6460674850a6da7511b2d2a7"),
name: 'liming',
age: 18
},
{ _id: ObjectId("6460674850a6da7511b2d2aa"), name: 'laose', age: 29 },
{ _id: ObjectId("6460674850a6da7511b2d2ab"), name: 'make', age: 14 },
{
_id: ObjectId("6460674850a6da7511b2d2ac"),
name: 'selltye',
age: 22
},
{ _id: ObjectId("6460674850a6da7511b2d2ad"), name: 'gim', age: 19 }
]
mydb> db.user.drop()
true
mydb> db.user.find()
mydb>
结尾
这篇MongoDB文章是一篇面面俱到的入门级文章,旨在介绍MongoDB的基础原理和基础语法应用。文章主要分为三个部分:基础原理、基础语法和操作。在基础原理部分,文章介绍了MongoDB的定义和发展现状,以及与MySQL的对比。
本文使用了较大篇幅介绍基础语法部分,如介绍了MongoDB的软件版本、数据风格、字段名、点符号和用户管理等基础语法知识。在操作部分,文章介绍了常用的命令、数据库操作、集合操作、文档操作和删除文档等MongoDB的操作方法,并提供了实际的例子更好地理解和掌握MongoDB的基础语法和操作技巧。希望通过本文可以帮你更好的认识和使用MongoDB,也为自己所掌握的知识点做一下备忘。