MongoDB 是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展。它支持的数据结构非常松散,是一种类似于 JSON 的格式叫 BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。MongoDB 中的记录是一个文档,它是一个由字段和值对(field:value)组成的数据结构。MongoDB 文档类似于 JSON 对象,即一个文档认为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组。
适用场景:
- 数据量大
- 写入操作频繁
- 价值较低的数据
- 对事务性要求不高
对比 MySQL:
- MongoDB 更加灵活,可以存储多种数据类型
- MongoDB 更加适合分布式环境
- MongoDB 更加适合处理大量数据
安装:这里使用 docker 部署 mongoDB 和可视化工具。
.3.1 数据类型
MongoDB支持多种数据类型,这些数据类型可用于定义文档中的字段值。以下是MongoDB中常见的数据类型:
- String(字符串):存储文本数据,是最常见的数据类型。例如:“Hello, MongoDB”。
- Number(数字):存储数值数据。可以是整数或浮点数。例如:42 或 3.14。
- Boolean(布尔):存储布尔值,表示true或false。
- Array(数组):存储数组或列表。例如:[1, 2, 3]。
- Object(对象):存储嵌套文档或子文档。例如:{ key: “value”, nested: { key2: “value2” } }。
- ObjectId:存储12字节的十六进制数字,通常用于文档的唯一标识符。例如:ObjectId("5f631762b28d1d7aa8c6ef4d")。
- ISODate:存储日期和时间信息。例如:ISODate("2022-01-10T12:30:00Z")。
- Null:存储空值。例如:null。
- Regex(正则表达式):存储正则表达式。例如:/pattern/i。
- Binary Data(二进制数据):存储二进制数据,如图片、音频等。例如:BinData(0, "base64-encoded-data")。
- Code:存储JavaScript代码。例如:{ $code: "function() { return x + y; }" }。
- Timestamp:存储时间戳,通常用于记录文档的修改时间。例如:Timestamp(123456789, 1)。
在MongoDB中,我们可以使用多种查询操作符来满足不同的查询需求。以下是一些常用的逻辑操作符:
1. $and:使用$and操作符组合多个条件。例如,查询年龄在25到35之间的用户:
```javascript
db.collection.find({ age: { $gt: 25, $lt: 35 } })
```
2. $or:使用$or操作符组合多个条件中的任意一个成立。例如,查询年龄小于25或大于35的用户:
```javascript
db.collection.find({ $or: [{ age: { $lt: 25 } }, { age: { $gt: 35 } }] })
```
3. $not:使用$not操作符对指定条件取反。例如,查询年龄不等于25的用户:
```javascript
db.collection.find({ age: { $ne: 25 } })
```
4. $exists:使用$exists操作符检查字段是否存在。例如,查询字段age存在的用户:
```javascript
db.collection.find({ field: { $exists: true } })
```
5. $text:使用$text操作符进行全文本搜索,需要在创建索引时启用文本索引。例如,查询包含“search term”的文档:
```javascript
db.collection.find({ $text: { $search: "search term" } })
```
6. $in和$nin:使用$in和$nin操作符匹配字段值在给定数组中的文档。例如,查询年龄在[25, 30, 35]之间的用户:
```javascript
db.collection.find({ age: { $in: [25, 30, 35] } })
```
7. $gte和$lte:使用$gte和$lte操作符进行日期范围查询。例如,查询创建时间在2022-01-01至2022-12-31之间的用户:
```javascript
db.collection.find({ createdAt: { $gte: ISODate("2022-01-01"), $lte: ISODate("2022-12-31") } })
```
8. 结合多个条件创建更复杂的查询。例如,查询年龄大于等于25且名字以“A”开头的用户:
```javascript
db.collection.find({ age: { $gte: 25 }, name: { $regex: "^A" } })
```
投影查询还支持嵌套文档。例如,如果文档中有一个嵌套的地址字段,你可以通过指定嵌套字段来进行投影。
2.3.1 U基本操作符:$set:设置指定字段的值。如果不用set,会将整个文档重写成 { address: "123 Main St" },而不是只修改address属性。$unset:从文档中删除指定字段。
$inc:递增指定字段的值。$push:将值添加到数组字段。$pull:从数组字段中移除指定值。$addToSet:将值添加到集合字段,但仅当该值不存在时。还有很多更新操作符。https://www.mongodb.com/docs/manual/reference/operator/update/
要替换除_id字段之外的文档的全部内容,可以使用replaceOne(),替换文档可以具有与原始文档不同的字段。在替换文档中,可以省略_id字段,因为_id字段是不可变的;但是,如果包含id字段,则该字段的值必须与当前值相同。
2.3.1 D使用或方法删除集合中的文档。
3 索引MongoDB使用B树(或B-树)来实现索引。
3.1 索引分类:单字段索引、复合索引、文本索引、哈希/散列索引、TTL(生存时间)索引、多键索引、地理空间索引、稀疏索引。
该语句将为 createdAt 字段建立 TTL 索引,可以自动删除过期数据。TTL 索引会根据 expireAt 字段的值自动删除过期数据,可以用于数据清理等应用场景。该语句将为 tags 字段建立多键索引,可以加速查询包含指定标签的文档。多键索引会为数组中的每个元素建立一个索引,可以加速数组元素的查询。地理空间索引是针对地理位置信息建立的索引,可以支持地理位置查询;稀疏索引是 MongoDB 中的一种索引类型,用于对集合中某个字段的值进行索引,但仅包含具有该字段的文档。与普通索引不同,稀疏索引不会包含那些不包含指定字段的文档。
这将在 字段上创建一个稀疏索引,只包含那些包含 字段的文档。稀疏索引对于只有一小部分文档包含某个字段值的情况非常有用,可以节省索引空间并提高查询性能。
唯一索引确保索引字段的值在整个集合中是唯一的。在创建集合并使用 方法时,MongoDB 在 字段上创建一个唯一的索引,默认名字为 ,该索引可防止客户端插入两个具有相同值的文档 ,不能在 字段上删除此索引。注意:该索引是唯一索引,因此值不能重复,即 值不能重复的。
要创建索引,可以使用 createIndex() 方法。要删除索引,可以使用 dropIndex() 方法。要删除所有索引(除了默认的_id 索引),可以使用 dropIndexes() 方法。
性能分析选项包括以下类型:
- COLLSSCAN:全表扫描
- IXSCAN:索引扫描
- FETCH:根据索引去检索指定document
- SHARD_MERGE:将各个分片返回数据进行merge
- SORT:表明在内存中进行了排序
- LIMIT:使用limit限制返回数
- SKIP:使用skip进行跳过
- IDHACK:针对_id进行查询
- SHARDING_FILTER:通过mongos对分片数据进行查询
- COUNT:利用db.coll.explain().count()之类进行count运算
- TEXT:使用全文索引进行查询时候的stage返回
- PROJECTION:限定返回字段时候stage的返回
优秀组合包括:
- Fetch+IDHACK
- Fetch+IXSCAN
- Limit+(Fetch+IXSCAN)
- PROJECTION+IXSCAN
- SHARDING_FITER+IXSCAN
需要优化的组合包括:
- COLSCAN(全表扫描)
- SORT(使用sort但是无index)
- COUNT 不使用index进行count)
覆盖查询(Covered Query)是一种查询优化技术,通过使用索引,可以使查询在索引中找到所有所需的字段,而无需回到集合中去检索文档。这可以提高查询性能,因为不需要额外的磁盘 I/O 来获取文档数据,而是直接从索引中获取所需的信息。覆盖查询的关键是确保查询条件和投影字段都可以通过索引满足。具体来说:
在MongoDB查询中,为了提高查询性能,我们可以采用覆盖查询。覆盖查询是指在查询时直接从索引中获取所需数据,而不需要回到集合中检索文档数据。为了实现覆盖查询,我们需要确保查询条件中的所有字段都是索引字段,以及投影字段也包含在索引中。
在这个查询中,查询条件是 ,这个条件可以通过 索引直接匹配。投影字段是 ,这些字段也可以从索引中直接获取。因此,这是一个覆盖查询,不需要回到集合中检索文档数据。
参考链接:
1. MongoDB 查询优化之覆盖查询(上)-CSDN博客
2. MongoDB 查询优化之覆盖查询(下)-CSDN博客