夏溪辰的博客

xiaxichen's blog

Mongo 数据结构&基础操作

25
2023-12-04

Mongo 数据结构&基础操作

简介

MongoDB是一种开源的面向文档的NoSQL数据库管理系统,它提供了高性能、可扩展和灵活的数据存储解决方案。下面是一些MongoDB的关键特点和概念:

  1. 面向文档:MongoDB使用类似JSON的BSON(二进制JSON)格式来存储数据。它以文档的形式组织数据,每个文档是一个键值对的集合,类似于关系型数据库中的行(row)或文档数据库中的记录。文档可以嵌套和包含各种类型的数据。
  2. 可扩展性:MongoDB支持水平扩展,可以通过添加更多的服务器节点来处理大规模的数据和负载。它使用分片(Sharding)技术将数据分布到多个服务器上,以实现高吞吐量和高并发性。
  3. 灵活的数据模型:MongoDB的文档模型非常灵活,没有严格的模式要求。这意味着可以根据需要动态地修改文档结构,而无需事先定义表结构。这样的灵活性使得MongoDB适用于快速迭代和需求变化频繁的应用程序开发。
  4. 查询语言:MongoDB提供了丰富的查询语言和功能,包括灵活的查询表达式(续):
    • 筛选条件:可以使用丰富的查询运算符和条件来筛选文档。
    • 投影:可以选择性地指定要返回的字段,以减少网络传输和提高查询性能。
    • 聚合框架:支持强大的聚合管道功能,可以对文档进行聚合、分组、排序和转换等操作。
  5. 数据复制和高可用性:MongoDB支持数据复制和故障恢复。通过复制集(Replica Set)机制,可以将数据复制到多个服务器上,以提供数据冗余和故障容错。当主节点发生故障时,复制集会自动选举新的主节点,实现自动故障转移。
  6. 数据安全性:MongoDB提供了各种安全功能,包括身份验证、访问控制、加密传输和审计日志等。这些功能可以帮助保护数据免受未经授权的访问和恶意攻击。
  7. 支持丰富的功能和工具:MongoDB提供了许多附加功能和工具,如全文搜索、地理空间索引、图形查询、数据备份和恢复等。还有各种语言驱动程序和集成工具,使得与MongoDB进行交互和开发变得更加方便。

MongoDB在许多场景下都被广泛应用,特别适合需要灵活性、可扩展性和高性能的应用程序,如Web应用、实时分析、日志存储、内容管理系统等。它的设计理念使得开发人员能够更快地迭代和部署应用程序,同时提供可靠的数据存储和查询能力。

数据结构

MongoDB使用BSON(Binary JSON)格式来存储数据。BSON是一种二进制编码的JSON扩展,它支持更多的数据类型和特性。下面是MongoDB中常见的数据格式:

  1. 文档(Document):
    • 文档是MongoDB中最基本的数据单元,类似于关系型数据库中的行(row)或文档数据库中的记录。

    • 文档由一组键值对组成,键是字符串,值可以是各种数据类型,包括字符串、数字、布尔值、日期、数组、嵌套文档等。

    • 例如,以下是一个MongoDB文档的示例:
      json

      {
        "_id": ObjectId("5f8e3e9b3f8e3b7d9a27c6e1"),
        "name": "John Doe",
        "age": 30,
        "email": "johndoe@example.com",
        "address": {
          "street": "123 Main St",
          "city": "New York",
          "country": "USA"
        },
        "hobbies": ["reading", "traveling", "sports"]
      }
      
  2. 集合(Collection):
    • 集合是一组相关文档的容器,类似于关系型数据库中的表(table)。
    • 集合中的文档可以具有不同的结构,没有严格的模式要求,这使得MongoDB非常灵活。
    • 例如,可以创建一个名为"users"的集合来存储用户文档。
  3. 数据库(Database):
    • 数据库是MongoDB中的逻辑容器,用于组织集合。
    • 一个MongoDB服务器可以包含多个数据库,每个数据库都可以包含多个集合。
    • 例如,可以创建一个名为"mydb"的数据库,其中包含"users"集合。
  4. ObjectId:
    • ObjectId是MongoDB中文档默认自动生成的唯一标识符。
    • ObjectId是一个12字节的值,由时间戳、机器ID、进程ID和自增计数器组成,保证了全局唯一性。
    • ObjectId可用于快速排序和索引,也可用于在分布式环境中标识和跟踪文档。
  5. 数组(Array):
    • 数组是MongoDB中的一种数据类型,可以存储多个值。
    • 数组可以包含各种数据类型的元素,包括字符串、数字、布尔值、日期、嵌套文档、其他数组等。
    • 例如,在上面的示例文档中,"hobbies"字段是一个字符串数组。

MongoDB的数据格式非常灵活,没有严格的模式要求,允许嵌套和多样化的数据结构。这使得MongoDB适用于处理不规则、变化频繁的数据,并支持动态模式演化。

操作符(太复杂了建议查询时候直接检索)

MongoDB提供了丰富的操作符,用于查询和操作文档中的数据。下面是一些常用的MongoDB操作符的介绍:

  1. 查询操作符:
    • $eq:匹配字段值等于指定值的文档。
    • $ne:匹配字段值不等于指定值的文档。
    • $gt$gte:匹配字段值大于(或大于等于)指定值的文档。
    • $lt$lte:匹配字段值小于(或小于等于)指定值的文档。
    • $in:匹配字段值在指定数组中的文档。
    • $nin:匹配字段值不在指定数组中的文档。
    • $exists:匹配存在(或不存在)指定字段的文档。
    • $regex:使用正则表达式匹配指定字段的文档。
  2. 逻辑操作符:
    • $and$or$not:用于在查询中组合多个条件,进行逻辑与、逻辑或、逻辑非操作。
    • $nor:匹配不满足任何条件的文档。
  3. 字段操作符:
    • $exists:检查字段是否存在。
    • $type:检查字段的数据类型。
    • $size:检查数组字段的大小。
    • $elemMatch:在数组字段中进行复杂条件查询。
  4. 更新操作符:
  • $set:将字段设置为指定值。
  • $unset:移除字段。
  • $inc:对数字字段进行增加或减少操作。
  • $push:向数组字段中添加元素。
  • $pull:从数组字段中移除匹配条件的元素。
  • $addToSet:向数组字段中添加元素,如果元素已存在则不重复添加。
  • $rename:重命名字段。
  1. 聚合操作符:

    • $group:按指定条件对文档进行分组。
    • $match:根据指定条件筛选文档。
    • $project:选择要返回的字段,进行投影操作。
    • $sort:对文档进行排序。
    • $limit:限制返回的文档数量。
    • $skip:跳过指定数量的文档。
  2. 数组操作符:

    • $all:匹配包含指定所有元素的数组字段。
    • $elemMatch:在数组字段中进行复杂条件查询。
    • $size:匹配数组字段的长度。
  3. 字段更新操作符:

    • $currentDate:将字段的值设置为当前日期或当前时间戳。
    • $mul:将数字字段的值乘以指定的因子。
    • $min:如果字段的值小于指定值,则更新字段的值。
    • $max:如果字段的值大于指定值,则更新字段的值。
  4. 数组更新操作符:

    • $addToSet:向数组字段中添加元素,如果元素已存在则不重复添加。
    • $pop:从数组字段中删除第一个或最后一个元素。
    • $pull:从数组字段中删除匹配指定条件的元素。
    • $push:向数组字段中添加元素。
    • $pullAll:从数组字段中删除匹配指定值的所有元素。
  5. 文本搜索操作符:

    • $text:执行全文本搜索。
    • $search:指定要搜索的文本。
    • $language:指定搜索的语言。
  6. 日期操作符:

    • $dateToString:将日期字段格式化为指定的字符串形式。
    • $isoWeek:返回日期字段所在的ISO周数。
    • $dayOfYear:返回日期字段所在的年份中的第几天。
    • $year$month$dayOfMonth:返回日期字段的年、月、日。
  7. 条件操作符:

    • $cond:根据指定条件返回不同的值。
    • $switch:根据多个条件进行条件判断。
  8. 位操作符:

    • $bit:对整数字段执行位操作,如与、或、异或等。

这只是MongoDB操作符的一小部分,MongoDB还提供了许多其他操作符和功能,如地理空间操作符等。使用这些操作符,您可以灵活地构建复杂的查询和更新操作,以满足您的数据处理需求。建议查阅MongoDB官方文档以获取更详细的信息和示例。

索引

种类

当数据库中的数据量增加时,使用索引可以大幅提升查询性能。MongoDB提供了多种类型的索引,以满足各种查询需求。以下是MongoDB中常见的索引类型:

  1. 单字段索引(Single Field Index):最常见的索引类型,基于单个字段创建。可以通过在字段上创建索引来加速对该字段的查询。
  2. 复合索引(Compound Index):由多个字段组成的索引。复合索引可以提高多个字段组合查询的性能,尤其是当这些字段经常一起被查询时。
  3. 唯一索引(Unique Index):确保索引字段的值在整个集合中是唯一的。唯一索引可以防止重复值的插入,并加速对唯一字段的查询。
  4. 文本索引(Text Index):用于执行全文本搜索的索引类型。文本索引可以对文本字段进行文本搜索和匹配操作,支持对自然语言的查询。
  5. 地理空间索引(Geospatial Index):用于处理地理空间数据的索引类型。地理空间索引可以加速对地理位置信息的查询,例如查找附近的位置或者在特定区域内的位置。
  6. 散列索引(Hashed Index):将索引字段的值进行散列哈希后创建的索引。散列索引可以提供更好的随机读取性能,但不支持范围查询。
  7. TTL索引(Time-To-Live Index):用于自动过期文档的索引类型。TTL索引可以设置文档的过期时间,当达到过期时间后,MongoDB将自动删除这些文档。
  8. 多键索引(Multikey Index):针对数组字段的索引类型。多键索引可以对数组中的每个元素创建索引,以支持数组字段的查询和排序。

此外,MongoDB还支持稀疏索引(Sparse Index)、部分索引(Partial Index)等高级索引类型,用于更精细地控制索引的创建和使用。根据具体的应用需求和查询模式,选择适当的索引类型可以提高查询性能和数据库的整体效率。

建议

在MongoDB中,索引是提高查询性能的关键因素之一。正确地建立索引可以显著加速查询操作并减少数据库的负载。下面是一些关于如何建立MongoDB索引的指导原则:

  1. 选择适当的字段:根据查询的需求和模式,选择合适的字段作为索引字段。通常情况下,经常用于查询和过滤的字段是理想的索引候选者。
  2. 考虑查询的频率和复杂性:针对经常执行的查询,建立索引可以显著提高性能。同时,对于复杂的查询,可能需要建立多个字段的组合索引来满足查询条件。
  3. 索引选择性:选择具有高选择性的字段作为索引字段,即能够尽可能减少索引中重复值的字段。这样可以提高索引的效率和性能。
  4. 考虑内存和磁盘使用:索引需要占用内存和磁盘空间。因此,在建立索引时需要权衡内存和磁盘的使用,避免过度索引导致资源浪费。
  5. 建立复合索引:对于经常一起使用的字段,建立复合索引可以提高查询性能。复合索引是包含多个字段的索引,可以更好地支持多字段的查询。
  6. 了解索引类型:MongoDB支持多种类型的索引,包括普通索引、唯一索引、稀疏索引、全文本索引、地理空间索引等。理解不同类型的索引,并根据需求选择适当的索引类型。
  7. 监控索引性能:建立索引后,定期监控索引的性能和使用情况。根据实际情况,可以进行索引优化、重新建立索引或删除无用的索引。
  8. 考虑数据增长和更新的影响:在建立索引时,需要考虑数据的增长和更新对索引的影响。频繁的数据更新可能导致索引效率下降,因此需要综合考虑索引的维护成本和查询性能。

建立索引是一个权衡和优化的过程,需要根据具体的应用需求和查询模式来选择适当的索引策略。建议在设计数据库架构时就考虑索引的需求,并进行性能测试和优化,以获得最佳的查询性能。

增删改查

当使用MongoDB进行基本的增删改查操作时,可以使用以下命令和示例:

  1. 插入文档(Insert Document):
    使用 insertOne()方法插入单个文档:

    db.collectionName.insertOne({ field1: value1, field2: value2, ... });
    

    使用 insertMany()方法插入多个文档:

    db.collectionName.insertMany([
      { field1: value1, field2: value2 },
      { field1: value3, field2: value4 },
      ...
    ]);
    
  2. 查询文档(Query Document):
    使用 find()方法查询匹配条件的文档:

    db.collectionName.find({ field: value });
    

    使用 findOne()方法查询并返回第一个匹配的文档:

    db.collectionName.findOne({ field: value });
    
  3. 更新文档(Update Document):
    使用 updateOne()方法更新匹配条件的单个文档:

    db.collectionName.updateOne({ field: value }, { $set: { fieldToUpdate: newValue } });
    

    使用 updateMany()方法更新匹配条件的多个文档:

    db.collectionName.updateMany({ field: value }, { $set: { fieldToUpdate: newValue } });
    
  4. 删除文档(Delete Document):
    使用 deleteOne()方法删除匹配条件的单个文档:

    db.collectionName.deleteOne({ field: value });
    

    使用 deleteMany()方法删除匹配条件的多个文档:

    db.collectionName.deleteMany({ field: value });
    

以上是MongoDB中基本的增删改查操作的示例。需要注意的是,collectionName应替换为实际的集合名称,fieldvalue应替换为实际的字段和值。另外,还可以使用各种查询条件、操作符和选项来进一步定制和优化这些操作。

管道操作

操作符

在MongoDB中,管道操作是一种强大的数据聚合工具,它通过将多个操作连接在一起,按照特定的顺序对文档进行转换和处理。管道操作可以用于数据聚合、数据转换、数据筛选等多种场景。下面是MongoDB中常用的管道操作:

  1. $match:用于筛选文档,只返回满足指定条件的文档。类似于查询操作中的 find()
  2. $project:用于选择要返回的字段,可以重命名字段、添加计算字段等。类似于查询操作中的 find()的投影操作。
  3. $group:用于对文档进行分组操作,根据指定的字段对文档进行分组,并进行聚合计算,如求和、平均值、计数等。
  4. $sort:用于对文档进行排序操作,可以指定要排序的字段以及排序方式(升序或降序)。
  5. $limit:用于限制返回的文档数量,只返回指定数量的文档。
  6. $skip:用于跳过指定数量的文档,从指定位置开始返回文档。
  7. $unwind:用于将包含数组的文档拆分成多个文档,每个数组元素对应一个新的文档。
  8. $lookup:用于在多个集合之间进行类似于SQL的连接操作,根据字段的关联关系将文档连接起来。
  9. $project和$group中的表达式操作符:可以在管道操作中使用多种表达式操作符,如算术操作、逻辑操作、日期操作等,对文档进行计算和转换。

这些管道操作可以按照需要组合和嵌套,构建复杂的数据处理流程。管道操作可以通过使用聚合框架(Aggregation Framework)实现,例如使用 aggregate()方法执行管道操作。

demo

以下是一个简单的管道操作示例,使用 $match筛选文档,然后使用 $group进行分组计算:

db.collectionName.aggregate([
  { $match: { field: value } },
  { $group: { _id: "$field", count: { $sum: 1 } } }
])

在这个示例中,首先使用 $match筛选出 field字段等于 value的文档,然后使用 $group将满足条件的文档按照 field字段进行分组,并计算每个分组中的文档数量。

MongoDB的管道操作提供了强大的数据处理能力,可以根据实际需求和复杂度灵活使用不同的操作符和操作组合。更多关于管道操作的详细信息和用法可以参考MongoDB的官方文档。