MongoDB基本概念
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
MongoDB中的记录是一个文档,它是由字段和值对组成的数据结构。MongoDB文档类似于JSON对象。字段的值可以包括其他文档,数组和文档数组。
MongoDB将文档存储到集合中(collections),集合类似于关系数据库中的表。
数据库
进入mongodb shell
mongo
查看当前数据库
db
切换当前数据库,如果该数据库不存在则会被创建。
use 数据库名称
展示所有数据库
show dbs
集合
MongoDB将文档存储在集合中。集合类似于关系数据库中的表。
展示当前数据库中所有集合
show collections
创建集合,当插入文档时,如果发现集合不存在则会自动创建该集合。
也可以使用db.createCollection()
显示创建集合。
str
文档
MongoDB将数据记录存储为BSON文档。BSON是JSON文档的二进制表示形式,尽管它包含比JSON更多的数据类型。有关BSON规范,请参见bsonspec.org。另请参阅BSON类型。
MongoDB对字段名称有以下限制:
- 字段名称
_id
保留用作主键;它的值在集合中必须是唯一的,不可变的,并且可以是数组以外的任何类型。 - 字段名称不能包含
null
字符。 - 顶级字段名称不能以美元符号(
$
)字符开头。
BSON支持的的类型见BSON类型 - MongoDB-CN-Manual (mongoing.com)
MongoDB 增删改查
查询
通过db.collection.find()
进行查询
常见的查询
// 查看集合所有文档
db.collection.find()
// email == '123@qq.com'
db.collection.find({email: '123@qq.com'})
// email: '123@qq.com' && password: '123456'
db.collection.find({email: '123@qq.com',password: '123456'})
// email=='123@qq.com' || password=='123456'
db.collection.find({$or: [{email: '123@qq.com'},{password: '123456'}]})
// (email=='123@qq.com' || password=='123456') && name=='张三'
db.collection.find({name: "张三",$or: [{email: '123@qq.com'},{password: '123456'}]})
游标
db.collection.find()
实际上会返回一个游标,如果find()
方法返回没有被赋值给var
变量时,则会自动迭代,所以我们直接运行db.collection.find()
会返回所有文档。
var a = db.users.find() // 获取游标
a.hasNext() // true
a.next()
/*{
"_id" : ObjectId("627b4ad1e0c5cc9c94fdd468"),
"email" : "123@qq.com",
"password" : "123",
"role" : "用户",
"__v" : 0
}$1*/
手动迭代
while(a.hasNext()){ printjson(a.next()) }
// 或者
a.forEach(printjson)
printjson的作用是以JSON格式展示数据
以数组形式返回
a.toArray()
游标耗尽后或者shell空闲一段时间后会自动关闭游标
指定返回字段
指定只返回email
字段(_id默认也会返回)
db.users.find({},{email: 1})
指定不返回_id和__v
db.users.find({},{_id: 0,__v:0})
除_id字段外,不能在映射文档中同时使用包含和去除语句。
db.users.find({},{email: 1,password: 0}) // error
db.users.find({},{email: 1,_id: 0}) // true
嵌套文档
// 返回status=="A"的文档,并只返回字段
//_id字段(默认返回)、status字段和文档size中的uom字段
db.inventory.find(
{ status: "A" },
{ status: 1, "size.uom": 1 }
)
MongoDB 聚合
聚合管道
管道一般起着筛选和转换的作用(例如nestjs中的管道),MongoDB中的聚合管道也是如此。MongoDB 聚合管道由多个阶段组成。每个阶段在文档通过管道时转换文档。管道阶段不需要为每个输入文档生成一个输出文档;并且某些阶段可能会生成新文档或过滤掉文档。
以下面一段代码为例
db.orders.aggregate( [
// Stage 1: Filter pizza order documents by pizza size
{
$match: { size: "medium" }
},
// Stage 2: Group remaining documents by pizza name and calculate total quantity
{
$group: { _id: "$name", totalQuantity: { $sum: "$quantity" } }
}
] )
// 返回
{ "_id" : "Cheese", "totalQuantity" : 50 }
{ "_id" : "Pepperoni", "totalQuantity" : 20 }
{ "_id" : "Vegan", "totalQuantity" : 10 }
聚合管道经历了两个阶段:
- 第一阶段: 匹配所有size属性是"medium"的文档,即进行过滤。
- 第二阶段:按属性
name
对文档进行分组。 使用$sum来计算每个相同name
的quantity
之和。总计存储在聚合管道返回的 totalQuantity 字段中。
整个过程犹如一条管道,数据(集合中的文档)如同流水,从管道的一头流向另外一头,管道内进行一些处理,来确保最终管道出口流入的数据是我们所需要的。
聚合管道的特点:
- 每个阶段(stage)不需要为每个输入文档输出一个文档,例如,一些阶段可能会产生新的文档或者过滤某些文档。
- 除了
$out
,$merge
和$geoNear
外,其他的阶段可以多次出现在聚合管道中。 - 在阶段中计算平均值或者其他的计算,需要使用特定的聚合表达式
所有聚合表达式见: Aggregation Pipeline Quick Reference — MongoDB Manual
MongoDB Schema
MongoDB于SQL数据库其中很大的一个区别是MongoDB不需要你提前声明表(集合)的数据结构,这种灵活的方式有助于将文档映射到实体中,但是在实践中,我们仍然可以声明集合的文档结构并在更新和插入操作时进行验证。
Schema
MongoDB推荐使用JSON Schema来确定集合中的文档结构。
MongoDB文档中必须要有一个唯一的主键(ObjectId类型),默认情况下自动生成
_id
作为主键。
你可以在新建集合的时候指定Schema
db.createCollection( "contacts",
{ validator: { $or:
[
{ phone: { $type: "string" } },
{ email: { $regex: /@mongodb\.com$/ } },
{ status: { $in: [ "Unknown", "Incomplete" ] } }
]
}
} )
也可以为已有的集合指定Schema(使用JSONSchema模式)
db.runCommand( {
collMod: "contacts",
validator: { $jsonSchema: {
bsonType: "object",
required: [ "phone", "name" ],
properties: {
phone: {
bsonType: "string",
description: "must be a string and is required"
},
name: {
bsonType: "string",
description: "must be a string and is required"
}
}
} },
validationLevel: "strict",
validationAction: "error"
} )
validationLevel
表示验证级别
- strict(默认值): 严格验证级别,MongoDB会将验证规则应用于所有插入和更新。
- moderate: 中等验证级别,MongoDB 会将验证规则应用于已满足验证条件的现有文档的插入和更新。不会检查对不符合验证条件的现有文档的更新的有效性。
- off: 不验证
validationAction 表示是否接受无效(不符合规则)文档
- error(默认): MongoDB拒绝任何违反验证条件的插入或更新。
- warn: MongoDB将记录任何冲突,但允许插入或更新继续进行。
如果你要对集合进行规则检查,则可以执行
db.collection.validate()