开始
MongoDB 是一个基于文档的 NoSQL 数据库
官网:MongoDB
官方文档:MongoDB 文档
MongoDB 使用集合(Collections)来组织文档(Documents),每个文档都是由键值对组成的
- 数据库(Database):存储数据的容器,类似于关系型数据库中的数据库
- 集合(Collection):数据库中的一个集合,类似于关系型数据库中的表
- 文档(Document):集合中的一个数据记录,操作最小单位,类似于关系型数据库中的行,以 BSON 格式存储
相关术语对比
SQL 术语/概念 | MongoDB 术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB 不支持 | |
primary key | primary key | 主键,MongoDB 自动将 _id 字段设置为主键 |
基本操作
基本命令
show dbs
:查看所有数据库use my_db
:使用数据库,MongoDB 中的数据库不需要手动创建,当添加文档时,数据库会自动创建show collections
:查看当前数据库的集合db
:表示当前数据库,使用该对象操作当前数据库db.createCollection("myNewCollection")
:在当前数据库中创建集合,当添加文档时才创建db.myNewCollection.drop()
:删除集合db.dropDatabase()
:删除当前数据库
数据库 CRUD
插入文档
插入文档使用以下方法
insertOne()
:插入一个文档,传入一个 json 格式的对象insertMany()
:插入多个文档,传入一个数组
1 | db.myCollection.insertOne({ |
插入时如果没有指定
_id
字段,则自动创建唯一的_id
作为主键
更新文档
更新文档使用以下方法
updateOne
:更新一个文档updateMany
:更新多个文档replaceOne
:替换一个文档,替换除_id
字段之外的文档的所有内容
updateOne
方法和 updateMany
方法传入三个参数,分别是 fileter,update,options
- fileter:传入一个 json 对象,指定要过滤的 key,value 为一个值或一个表示条件的 json 对象
- update:传入一个 json 对象,通过操作符指定更新的行为
1 | db.myCollection.updateOne( |
删除文档
删除文档使用以下方法
deleteOne
:删除一个文档deleteMany
:删除多个文档
两个方法传入一个 fileter 参数和一个 options 参数,filter 参数指定过滤条件
1 | db.myCollection.deleteOne({ name: "Alice" }); |
查询文档
查询文档使用以下方法
find
:查询多个文档findOne
:查询一个文档
两个方法传入一个 filter 参数和 projection 参数,filter 参数指定过滤条件
1 | db.myCollection.find({ age: { $gt: 25 } }); |
projection 参数表示投影,指定返回的字段
1 | db.myCollection.find( |
其他查询操作
-
排序:sort 方法
1
2db.myCollection.find().sort({ age: -1 }); // 按age降序
db.myCollection.find().sort({ age: 1, name: -1 }); // 按age升序,按name降序 -
跳过:skip 方法
1
db.myCollection.find().skip(5); // 跳过前5个文档
-
限制:limit 方法
1
db.myCollection.find().limit(10); // 返回前10个文档
条件操作符
MongoDB 中使用一个 json 对象表示一个条件,条件操作符作为 key
比较操作符
比较操作符的 value 为一个值或一个数组
操作符 | 描述 | 示例 |
---|---|---|
$eq |
等于 | { age: { $eq: 25 } } |
$ne |
不等于 | { age: { $ne: 25 } } |
$gt |
大于 | { age: { $gt: 25 } } |
$gte |
大于等于 | { age: { $gte: 25 } } |
$lt |
小于 | { age: { $lt: 25 } } |
$lte |
小于等于 | { age: { $lte: 25 } } |
$in |
在指定的数组中 | { age: { $in: [25, 30, 35] } } |
$nin |
不在指定的数组中 | { age: { $nin: [25, 30, 35] } } |
逻辑操作符
逻辑操作符的 value 为一个数组,其中每个元素是一个条件 json 对象
操作符 | 描述 | 示例 |
---|---|---|
$and |
逻辑与,符合所有条件 | { $and: [ { age: { $gt: 25 } }, { city: "New York" } ] } |
$or |
逻辑或,符合任意条件 | { $or: [ { age: { $lt: 25 } }, { city: "New York" } ] } |
$not |
取反,不符合条件 | { age: { $not: { $gt: 25 } } } |
$nor |
逻辑与非,均不符合条件 | { $nor: [ { age: { $gt: 25 } }, { city: "New York" } ] } |
元素操作符
元素操作符指定元素相关的条件
操作符 | 描述 | 示例 |
---|---|---|
$exists |
字段是否存在 | { age: { $exists: true } } |
$type |
字段的 BSON 类型 | { age: { $type: "int" } } |
$regex |
字段值匹配正则表达式 | { name: { $regex: /^A/ } } |
数组操作符
操作符 | 描述 | 示例 |
---|---|---|
$all |
数组包含所有指定的元素 | { tags: { $all: ["red", "blue"] } } |
$elemMatch |
数组中的元素匹配指定条件 | { results: { $elemMatch: { score: { $gt: 80 } } } } |
$size |
数组的长度等于指定值 | { tags: { $size: 3 } } |
聚合操作
MongoDB 的聚合操作使用 aggregate
方法,传入一个数组,数组中的每个对象表示一个聚合管道,每个管道的返回值会作为下一个管道的输入,管道操作符如下
操作符 | 描述 |
---|---|
$project |
修改输入文档的结构,可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档 |
$match |
用于过滤数据,只输出符合条件的文档,使用 MongoDB 的标准查询操作 |
$limit |
用来限制 MongoDB 聚合管道返回的文档数 |
$skip |
在聚合管道中跳过指定数量的文档,并返回余下的文档 |
$unwind |
将文档中的某一个数组类型字段拆分成多个文档,每个文档的该字段为数组中的一个值 |
$group |
将集合中的文档分组,可用于统计结果 |
$sort |
将输入文档排序后输出 |
$project
将所有文档投影,不返回 _id
需要显示指定
1 | db.article.aggregate([ |
$match
接收一个条件 json 对象筛选匹配的文档
1 | db.article.aggregate([ |
$skip
下一个管道跳过指定数量文档
1 | db.article.aggregate([ |
$limit
指定输入下一个管道的文档数量
1 | db.article.aggregate([ |
$unwind
将文档中的某一个数组类型字段拆分成多个文档,每个文档的该字段为数组中的一个值,指定数组字段时在前面加 $
1 | // ages: [1, 2, 3] |
$sort
将文档排序后输出
1 | db.article.aggregate([ |
$group
将集合中的文档分组,可以使用聚合操作符来统计结果,接收的 json 对象包含两类字段
_id
:指定分组的字段,字段前加$
- field:自定义聚合结果字段名,接收一个 json 对象,其中使用聚合操作符作为 key,聚合字段作为 value
1 | db.article.aggregate([ |
常用聚合操作符如下
表达式 | 描述 |
---|---|
$sum |
计算总和 |
$avg |
计算平均值 |
$min |
获取集合中所有文档指定字段的最小值 |
$max |
获取集合中所有文档指定字段的最大值 |
$push |
将值加入一个数组中,不会判断是否有重复的值 |
$addToSet |
将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入 |
$first |
根据文档的排序获取第一个文档数据 |
$last |
根据文档的排序获取最后一个文档数据 |
数据库引用
mongodb 中不支持连接查询,在文档使用三个特殊字段来引用其他文档
引用的基本格式
1 | { |
e.g. 在 user 文档中引用 address 文档
1 | { |
在查询时需要分步查询
1 | var user = db.users.findOne({"name":"Tom Benzamin"}) |
ObjectId
mongodb 中默认使用 ObjectId 对象来作为 _id
字段的值,ObjectId 是一个 12 字节 BSON 类型数据,有以下格式
- 前 4 个字节表示时间戳
- 接下来的 3 个字节是机器标识码
- 紧接的 2 个字节由进程 id 组成(PID)
- 最后 3 个字节是随机数
调用 ObjectId()
创建 ObjectId,mongodb 会自动生成一个唯一 id
1 | var newObjectId = ObjectId() |
ObjectId 中存储了 4 个字节的时间戳,getTimestamp()
来获取时间戳
1 | var myId = ObjectId() |