一文读懂MongoDB的知识点(2),惊呆面试官。

在这里插入图片描述

作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。
多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。
欢迎 点赞✍评论⭐收藏

MongoDB知识专栏学习

MongoDB知识云集 访问地址 备注
MongoDB知识点(1) https://blog.csdn.net/m0_50308467/article/details/134739918 MongoDB专栏
MongoDB知识点(2) https://blog.csdn.net/m0_50308467/article/details/134798552 MongoDB专栏
MongoDB知识点(3) https://blog.csdn.net/m0_50308467/article/details/134806644 MongoDB专栏

文章目录

    • 一文读懂MongoDB(2)
      • 01、MongoDB在A:{B,C}上建立索引,查询A:{B,C}和A:{C,B}都会使用索引吗?
      • 02、如果一个分片(Shard)停止或很慢的时候,发起一个查询会怎样?
      • 03、MongoDB支持存储过程吗?如果支持的话,怎么用?
      • 04、如何理解MongoDB中的GridFS机制,MongoDB为何使用GridFS来存储文件?
      • 05、什么是NoSQL数据库?NoSQL和RDBMS有什么区别?在哪些情况下使用和不使用NoSQL数据库?
      • 06、说明Profiler在MongoDB中的作用是什么?
      • 07、分析器在MongoDB中的作用是什么?
      • 08、为什么MongoDB的数据文件很大?
      • 09、当更新一个正在被迁移的块(Chunk)上的文档时会发生什么?
      • 10、提到在MongoDB中使用索引的基本语法是什么?
      • 11、提及Objecld由什么组成?
      • 12、分析器在MongoDB中的作用是什么?
      • 13、如果用户移除对象的属性,该属性是否从存储层中删除?
      • 14、能否使用日志特征进行安全备份?
      • 15、更新操作立刻fsync到磁盘?
      • 16、如何执行事务/加锁?
      • 17、什么是master或primary?
      • 18、getLastError的作用?
      • 19、分片(sharding)和复制(replication)是怎样工作的?
      • 20、数据在什么时候才会扩展到多个分片(shard)里?
      • 21、当我试图更新一个正在被迁移的块(chunk)上的文档时会发生什么?
      • 22、我怎么查看 Mongo正在使用的链接?
      • 23、在MongoDb中如何添加索引?
      • 24、用什么方法可以格式化输出结果?
      • 25、如何使用"AND"或"OR"条件循环查询集合中的文档?
      • 26、在MongoDB中如何更新数据?
      • 27、如何删除文档?
      • 28、在MongoDB中如何排序?
      • 29、什么是聚合?
      • 30、在MongoDB中什么是副本集?

一文读懂MongoDB的知识点(2),惊呆面试官。_第1张图片

一文读懂MongoDB(2)

01、MongoDB在A:{B,C}上建立索引,查询A:{B,C}和A:{C,B}都会使用索引吗?

MongoDB 在 A:{B,C} 上建立索引,查询 A:{B,C} 和 A:{C,B} 都会使用索引。

MongoDB 的索引是基于 BSON 对象的,而 BSON 对象是无序的。因此,MongoDB 无法区分 A:{B,C} 和 A:{C,B}。当查询 A:{B,C} 或 A:{C,B} 时,MongoDB 都会使用 A:{B,C} 索引。

需要注意的是,MongoDB 的索引是单向的。因此,如果查询 A:{B,C} 或 A:{C,B},MongoDB 只能使用 A:{B,C} 索引的第一个元素 B 来进行排序。如果需要使用 A:{B,C} 索引的第二个元素 C 来进行排序,则需要创建一个新的索引 A:{C,B}。

02、如果一个分片(Shard)停止或很慢的时候,发起一个查询会怎样?

如果一个分片(Shard)停止或很慢的时候,发起一个查询,MongoDB 会尝试在其他分片上执行查询。如果其他分片上没有数据,MongoDB 会返回一个错误。

如果一个分片停止或很慢,MongoDB 会在 30 秒后重新尝试在该分片上执行查询。如果 30 秒后仍然无法在该分片上执行查询,MongoDB 会在其他分片上执行查询。

如果 MongoDB 无法在其他分片上执行查询,它会返回一个错误。

可以通过以下方式配置 MongoDB 以避免在分片停止或很慢时出现问题:

  • 启用副本集。副本集可以提供高可用性,如果一个分片停止或很慢,可以从其他分片中读取数据。

  • 使用分片键。分片键可以将数据均匀分布在多个分片上。如果一个分片停止或很慢,MongoDB 可以从其他分片中读取数据。

  • 使用内存缓存。内存缓存可以缓存查询结果,如果一个分片停止或很慢,MongoDB 可以从内存缓存中读取数据。

03、MongoDB支持存储过程吗?如果支持的话,怎么用?

MongoDB 不支持存储过程。

存储过程是存储在数据库中的一个程序,可以被其他程序调用。存储过程可以执行复杂的逻辑,并返回结果。

MongoDB 不支持存储过程,因为它是一个面向文档的数据库。文档是无结构的数据,不适合存储过程。

如果需要在 MongoDB 中执行复杂的逻辑,可以使用 JavaScript 函数。JavaScript 函数可以存储在数据库中,并被其他程序调用。

以下是一个使用 JavaScript 函数在 MongoDB 中执行复杂逻辑的例子:

function add(a, b) {
  return a + b;
}

db.collection.insert({
  "a": 1,
  "b": 2
});

db.collection.findOne({
  "a": 1,
  "b": 2
}).add(10);

在这个例子中,我们使用 JavaScript 函数 add 在 MongoDB 中执行加法运算。我们首先创建了一个 JavaScript 函数 add,它接受两个参数 a 和 b,并返回 a + b。然后,我们使用 db.collection.insert() 方法插入一个文档,该文档包含两个字段 a 和 b。

最后,我们使用 db.collection.findOne() 方法查询该文档,并使用 add 函数对 a 和 b 进行加法运算。

04、如何理解MongoDB中的GridFS机制,MongoDB为何使用GridFS来存储文件?

MongoDB 中的 GridFS 机制是一个文件存储系统,它允许用户在 MongoDB 中存储和检索二进制文件。GridFS 使用一个单独的集合来存储文件元数据,并使用一个单独的集合来存储文件数据。

MongoDB 使用 GridFS 来存储文件的原因有以下几点:

  • MongoDB 本身不支持二进制文件,因此需要使用 GridFS 来存储二进制文件。

  • GridFS 可以将文件分割成多个块,并将每个块存储在单独的文件中。这可以提高文件存储的效率,并减少文件存储的成本。

  • GridFS 可以使用分布式存储,这可以提高文件存储的可靠性。

  • GridFS 可以使用压缩来减少文件存储的大小。

以下是一个使用 GridFS 存储文件的示例:

  1. 创建一个 MongoDB 数据库。

  2. 创建一个 GridFS 集合。

  3. 使用 put() 方法将文件数据插入到 GridFS 集合中。

  4. 使用 get() 方法从 GridFS 集合中检索文件数据。

以下是一个使用 GridFS 存储文件的代码示例:

import pymongo

# 创建一个 MongoDB 数据库
client = pymongo.MongoClient()
db = client.mydb

# 创建一个 GridFS 集合
fs = db.fs

# 使用 put() 方法将文件数据插入到 GridFS 集合中
with open('myfile.txt', 'rb') as f:
    fs.put(f.read())

# 使用 get() 方法从 GridFS 集合中检索文件数据
with open('myfile.txt', 'wb') as f:
    f.write(fs.get().read())

更多关于 GridFS 的使用方法,请参考 MongoDB 官方文档:https://docs.mongodb.com/manual/core/gridfs/

05、什么是NoSQL数据库?NoSQL和RDBMS有什么区别?在哪些情况下使用和不使用NoSQL数据库?

NoSQL 数据库是一种非关系型数据库,它不使用关系模型来存储数据。NoSQL 数据库通常使用键值对、文档、列存储或图形来存储数据。

NoSQL 数据库和关系数据库(RDBMS)有以下区别:

  • 数据模型:关系数据库使用关系模型来存储数据,而 NoSQL 数据库使用不同的数据模型来存储数据。

  • 查询语言:关系数据库使用 SQL 来查询数据,而 NoSQL 数据库使用不同的查询语言来查询数据。

  • 扩展性:关系数据库的扩展性有限,而 NoSQL 数据库的扩展性更好。

  • 性能:关系数据库的性能通常比 NoSQL 数据库更高。

用表格说明其区别,如下:

类型 NoSQL 数据库 关系数据库
数据模型 键值对、文档、列存储、图形 关系模型
查询语言 不同的查询语言 SQL
扩展性 更好 有限
性能 通常比 NoSQL 数据库更高 更低
适用场景 大数据应用、高可用性应用、分布式应用 需要严格的数据完整性、需要复杂的查询、需要事务支持
不适用场景 需要严格的数据完整性、需要复杂的查询、需要事务支持 大数据应用、高可用性应用、分布式应用

NoSQL 数据库通常用于以下场景:

  • 大数据应用:NoSQL 数据库可以处理大量的数据。

  • 高可用性应用:NoSQL 数据库可以提供高可用性。

  • 分布式应用:NoSQL 数据库可以支持分布式应用。

NoSQL 数据库不适用于以下场景:

  • 需要严格的数据完整性:NoSQL 数据库不支持严格的数据完整性。

  • 需要复杂的查询:NoSQL 数据库不支持复杂的查询。

  • 需要事务支持:NoSQL 数据库不支持事务支持。

以下是一些常见的 NoSQL 数据库:

  • MongoDB
  • Cassandra
  • Redis
  • HBase
  • Neo4j

06、说明Profiler在MongoDB中的作用是什么?

在 MongoDB 中,Profiler 是一个用于记录数据库操作的工具,它可以帮助开发人员分析查询性能和诊断潜在的性能问题。

Profiler 可以捕获和记录 MongoDB 数据库中的操作,包括查询、更新、删除等操作。通过启用 Profiler,可以收集关于这些操作的详细信息,如执行时间、扫描文档的数量、命中索引的次数等。

Profiler 的作用主要有以下几点:

  1. 性能分析:Profiler 可以帮助开发人员分析查询的执行时间和资源消耗,以便找出潜在的性能瓶颈和优化查询。

  2. 查询优化:通过分析 Profiler 记录的查询信息,可以确定哪些查询需要进行索引优化或重写,以改善查询性能。

  3. 故障排除:Profiler 可以帮助识别导致数据库性能下降或查询执行时间过长的问题,并提供相关的诊断信息,以便进行故障排除和修复。

需要注意的是,启用 Profiler 会增加数据库的开销,因为它会记录大量的操作信息。因此,建议在需要进行性能分析或故障排除时才启用 Profiler,并在完成分析后及时禁用它。

07、分析器在MongoDB中的作用是什么?

在 MongoDB 中,分析器(Analyzer)是用于处理文本搜索和文本分析的组件。它的作用是将文本数据进行分词、标记化和规范化,以便进行全文搜索和文本分析。

分析器在 MongoDB 中的主要作用有以下几点:

  1. 分词(Tokenization):分析器将文本数据分割成词(Token)或词组,以便进行更精确的搜索和分析。分词可以根据特定的规则或算法进行,例如基于空格、标点符号或其他分隔符进行分割。

  2. 标记化(Tokenization):分析器将分词后的词或词组进行标记化,给每个词或词组赋予特定的标记。这些标记可以用于更精确地匹配搜索条件或进行文本分析。

  3. 规范化(Normalization):分析器对词或词组进行规范化,以消除大小写、重音符号、特殊字符等的差异,以便进行更准确的匹配和比较。

  4. 停用词过滤(Stop Words Filtering):分析器可以过滤掉常见的停用词,如 “and”、“the”、“is” 等,以减少不必要的搜索结果或提高搜索效率。

  5. 同义词扩展(Synonym Expansion):分析器可以将同义词或相关词扩展为相同的标记,以便在搜索时更全面地匹配相关的结果。

通过使用适当的分析器,可以提高 MongoDB 中的文本搜索和分析的准确性和效率。可以根据具体的需求和场景选择合适的分析器,或自定义分析器来满足特定的文本处理需求。

08、为什么MongoDB的数据文件很大?

MongoDB 的数据文件很大的原因可能有以下几点:

  • MongoDB 使用 BSON 格式存储数据,BSON 格式是二进制格式,比文本格式占用更多的空间。

  • MongoDB 使用多版本并发控制(MVCC)来实现数据库的并发读写,MVCC 会在数据库中保存多个版本的数据,这也会增加数据文件的大小。

  • MongoDB 使用分片来提高数据库的性能,分片会将数据分散到多个文件中,这也会增加数据文件的大小。

如果您希望减少 MongoDB 的数据文件大小,可以考虑以下几种方法:

  • 使用文本格式存储数据。

  • 使用单版本并发控制(SCC)来实现数据库的并发读写。

  • 将数据库拆分成多个较小的集合。

以下是一些关于 MongoDB 数据文件大小的常见问题:

  • MongoDB 数据文件的大小是多少?

MongoDB 数据文件的大小取决于数据库中的数据量和数据类型。一般来说,MongoDB 数据文件的大小会随着数据库中的数据量增加而增加。

  • 如何减少 MongoDB 数据文件的大小?

可以通过以下几种方法减少 MongoDB 数据文件的大小:

  • 使用文本格式存储数据。

  • 使用单版本并发控制(SCC)来实现数据库的并发读写。

  • 将数据库拆分成多个较小的集合。

  • MongoDB 数据文件的大小有没有限制?

MongoDB 数据文件的大小没有限制。但是,如果数据文件太大,可能会影响数据库的性能。

  • 如何查看 MongoDB 数据文件的大小?

可以使用以下命令查看 MongoDB 数据文件的大小:

db.stats()

这个命令会返回 MongoDB 数据库的统计信息,其中包括数据文件的大小。

09、当更新一个正在被迁移的块(Chunk)上的文档时会发生什么?

当更新一个正在被迁移的块(Chunk)上的文档时,MongoDB 会将更新后的文档写入新的目标分片,并将旧的版本的文档保留在原始分片中。

这样做是为了确保数据的一致性。如果不这样做,可能会导致数据在不同的分片上有不同的版本。

MongoDB 会在更新后的文档写入新的目标分片后,将旧的版本的文档标记为过期。过期文档将在一定时间后被删除。

可以通过以下命令查看正在被迁移的块:

db.admin.command('listCollections', {
  'filter': {
    'migrationStatus': {
      '$ne': 'completed'
    }
  }
})

这个命令会返回正在被迁移的集合的列表。

可以通过以下命令查看正在被迁移的块的详细信息:

db.admin.command('listCollections', {
  'filter': {
    'migrationStatus': {
      '$ne': 'completed'
    }
  },
  'showDiskLoc': true
})

这个命令会返回正在被迁移的集合的列表,以及每个集合正在被迁移的块的详细信息。

可以通过以下命令查看正在被迁移的块上的文档:

db.admin.command('listCollections', {
  'filter': {
    'migrationStatus': {
      '$ne': 'completed'
    }
  },
  'showDiskLoc': true,
  'find': {
    '_id': 'chunk_id'
  }
})

这个命令会返回正在被迁移的块上的文档。

可以通过以下命令查看正在被迁移的块上的过期文档:

db.admin.command('listCollections', {
  'filter': {
    'migrationStatus': {
      '$ne': 'completed'
    }
  },
  'showDiskLoc': true,
  'find': {
    '_id': 'chunk_id',
    'migrationStatus': 'expired'
  }
})

这个命令会返回正在被迁移的块上的过期文档。

10、提到在MongoDB中使用索引的基本语法是什么?

在 MongoDB 中使用索引的基本语法如下:

1. 创建索引:

db.collection.createIndex({ field: 1 })

这将在集合中的指定字段上创建升序索引。可以使用 -1 来创建降序索引。

2. 查询时使用索引:

db.collection.find({ field: value }).hint({ field: 1 })

这将在查询时指定使用特定的索引。

3. 查看索引:

db.collection.getIndexes()

这将显示集合中的所有索引。

4. 删除索引:

db.collection.dropIndex({ field: 1 })

这将删除指定字段上的索引。

需要注意的是,索引可以提高查询性能,但也会增加存储空间和写入性能的开销。因此,在创建索引时需要权衡查询性能和存储/写入开销。

此外,MongoDB 还支持更高级的索引选项,如复合索引、文本索引、地理空间索引等。可以根据具体需求和数据模型选择适当的索引类型。

11、提及Objecld由什么组成?

对象(Object)是计算机编程中的一个概念,它由一组属性(Properties)组成。

属性是对象的特征或数据,它们描述了对象的状态和行为。每个属性由一个键(Key)和一个值(Value)组成。键是属性的名称,值是属性的具体内容或数据。

对象的属性可以包含不同的数据类型,如字符串、数字、布尔值、数组、甚至其他对象。这使得对象可以灵活地表示和组织复杂的数据结构。

例如,考虑一个名为"person"的对象,它可以具有属性如下:

person = {
  name: "John",
  age: 30,
  isEmployed: true,
  hobbies: ["reading", "swimming"],
  address: {
    street: "123 Main St",
    city: "New York",
    country: "USA"
  }
};

在上面的示例中,“person"对象具有名为"name”、“age”、“isEmployed”、"hobbies"和"address"的属性。其中,"name"是一个字符串,"age"是一个数字,"isEmployed"是一个布尔值,"hobbies"是一个数组,"address"是一个嵌套的对象。

通过这些属性,我们可以访问和操作对象中的数据,例如使用"person.name"来获取姓名,或使用"person.hobbies[0]"来获取第一个爱好。对象的属性提供了一种组织和访问数据的方式。

12、分析器在MongoDB中的作用是什么?

分析器在 MongoDB 中的作用是将文档中的字段转换为 BSON 格式。BSON 格式是 MongoDB 使用的二进制数据格式。分析器会将文档中的字段转换为 BSON 格式,以便 MongoDB 可以更有效地存储和检索数据。

分析器可以通过以下方式配置:

  • 在创建集合时指定分析器。

  • 在创建文档时指定分析器。

  • 使用 update() 方法更新文档时指定分析器。

如果没有指定分析器,MongoDB 会使用默认分析器。默认分析器会将所有字段转换为字符串。

以下是一些常见的分析器:

  • text : 将字段转换为文本。

  • date : 将字段转换为日期。

  • number : 将字段转换为数字。

  • array : 将字段转换为数组。

可以通过以下命令查看 MongoDB 中所有可用的分析器:

db.admin.command('listCollections', {
  'filter': {
    'type': 'analysis'
  }
})

这个命令会返回 MongoDB 中所有可用的分析器。

13、如果用户移除对象的属性,该属性是否从存储层中删除?

如果用户移除对象的属性,该属性不会从存储层中删除。

MongoDB 使用 BSON 格式存储数据。BSON 格式是一种二进制数据格式,它可以存储各种类型的数据,包括字符串、数字、数组、对象等。

当用户移除对象的属性时,MongoDB 会将该属性从对象中删除,但不会从存储层中删除。这意味着,如果用户再次访问该对象,该属性仍然存在。

如果用户希望从存储层中删除属性,可以使用 unset() 方法。 unset() 方法可以删除对象中的任何属性,包括内嵌对象中的属性。

以下是一个使用 unset() 方法删除属性的示例:

db.collection.updateOne({
  '_id': 'my_document'
}, {
  $unset: {
    'my_property': 1
  }
})

这个命令会从 my_document 文档中删除 my_property 属性。

14、能否使用日志特征进行安全备份?

MongoDB 的日志功能可以用来进行安全备份。

MongoDB 的日志功能会记录所有对数据库进行的更改。这些更改会被记录在日志文件中。如果数据库发生故障,可以使用日志文件来恢复数据库。

为了使用日志功能进行安全备份,需要在 MongoDB 配置文件中启用日志功能。启用日志功能后,MongoDB 会在日志文件中记录所有对数据库进行的更改。

当需要恢复数据库时,可以使用日志文件来恢复数据库。恢复数据库时,需要使用 mongorestore 命令。

以下是一个使用 mongorestore 命令恢复数据库的示例:

mongorestore --db mydb --collection mycollection --drop --journal mybackup.log

这个命令会使用 mybackup.log 日志文件来恢复 mydb 数据库中的 mycollection 集合。

需要注意的是,使用日志功能进行安全备份需要在 MongoDB 配置文件中启用日志功能。如果没有启用日志功能,MongoDB 不会记录任何对数据库进行的更改。

15、更新操作立刻fsync到磁盘?

默认情况下,MongoDB 在执行更新操作时不会立即将数据写入磁盘。它使用写时复制(copy-on-write)策略,将更新写入内存中的写操作日志(Write-Ahead Log,WAL),并在后台异步地将数据刷新到磁盘。

这种延迟写入的策略有助于提高写入性能,因为它避免了每次更新操作都要等待数据写入磁盘的开销。相反,MongoDB 将更改写入内存中的写操作日志,然后定期将数据批量刷新到磁盘。

但是,您可以使用 writeConcern 选项来强制 MongoDB 在执行写操作时立即将数据刷新到磁盘。 writeConcern 允许您控制写操作的持久性要求。

以下是一个示例,演示如何在更新操作中使用 writeConcern 选项:

db.collection.updateOne(
  { <query> },
  { <update> },
  { writeConcern: { w: "majority", j: true } }
)

在上面的示例中, writeConcern 设置为 { w: "majority", j: true } ,表示在更新操作完成后,至少要将数据写入大多数副本集成员,并且要求使用日志持久化(journaling)。

需要注意的是,将 writeConcern 设置为强制立即刷新到磁盘可能会对性能产生一定的影响。因此,您需要根据应用程序的需求和性能要求来权衡使用。

16、如何执行事务/加锁?

MongoDB 不支持事务,但它支持加锁。

MongoDB 使用以下几种类型的锁:

  • 共享锁:允许多个线程同时访问数据,但只能读取数据,不能修改数据。

  • 排他锁:只允许一个线程访问数据,并且可以读取和修改数据。

MongoDB 使用以下几种方法来获取锁:

  • 自动获取锁:MongoDB 会自动获取锁,不需要用户手动获取。

  • 手动获取锁:用户可以使用 lock() 方法手动获取锁。

MongoDB 使用以下几种方法来释放锁:

  • 自动释放锁:MongoDB 会自动释放锁,不需要用户手动释放。

  • 手动释放锁:用户可以使用 unlock() 方法手动释放锁。

以下是一个使用 MongoDB 加锁的示例:

db.collection.findOneAndUpdate(
  { _id: 1 },
  { $set: { name: "John" } },
  {
    upsert: true,
    lock: true
  }
)

在这个示例中,我们使用 lock: true 选项来获取一个排他锁。这意味着,只有一个线程可以同时访问这个文档,并且可以读取和修改数据。

当我们完成对文档的修改后,我们使用 unlock() 方法来释放锁。

需要注意的是,MongoDB 的锁是基于集合的,这意味着,如果我们在一个集合上获取了一个锁,那么我们就不能同时访问其他集合。

17、什么是master或primary?

在分布式系统中,“master” 或 “primary” 是指拥有主要责任和权限的节点或副本集成员。在MongoDB中,“master” 或 “primary” 是指副本集中的主节点。

在MongoDB的副本集中,有一个主节点(primary)和多个从节点(secondary)。主节点是唯一具有写入权限的节点,它负责处理所有写入操作,并将写入操作的结果复制到从节点。从节点只负责复制主节点的数据,它们可以用于读取操作,但不具备写入权限。

主节点在副本集中起着关键的作用,它负责处理客户端的写入请求,并确保数据的一致性和持久性。如果主节点发生故障或不可用,副本集会自动从从节点中选举出一个新的主节点来接管主节点的职责。

需要注意的是,主节点的选择是动态的,当主节点发生故障或不可用时,副本集会自动进行主节点选举,确保系统的高可用性和容错性。

18、getLastError的作用?

getLastError 是一个用于获取最近一次写入操作的错误信息的命令。它用于检查 MongoDB 写入操作的结果,以便确定是否发生了错误或异常情况。

当执行写入操作(如插入、更新或删除)时,MongoDB 可能会返回一些错误信息,如网络错误、写入冲突或写入超时等。getLastError 命令可以用于获取这些错误信息。

使用 getLastError 命令的基本语法如下:

db.runCommand({ getLastError: 1 })

执行该命令后,MongoDB 将返回最近一次写入操作的错误信息,包括错误代码、错误消息和其他相关信息。

getLastError 命令还可以与其他写入操作一起使用,例如在执行写入操作后立即调用 getLastError 命令,以确保写入操作已成功完成。

需要注意的是,自 MongoDB 3.2 版本开始,getLastError 已经不再是必需的,因为大多数写入操作都具有默认的写入确认机制(write concern)。但在某些情况下,仍然可以使用 getLastError 来获取更详细的错误信息。

19、分片(sharding)和复制(replication)是怎样工作的?

分片(Sharding)和复制(Replication)是 MongoDB 中用于扩展和提高数据可用性的两种关键技术。

分片(Sharding)

分片是将数据分散存储在多个节点(分片)上的过程。它允许将数据集划分为多个片(Chunks),并将这些片分布在不同的分片节点上。每个分片节点都是一个独立的 MongoDB 实例,可以在不同的物理服务器上运行。

当使用分片时,MongoDB会根据指定的分片键将数据分布到不同的分片节点上。分片键是数据集中的一个字段,MongoDB使用它来决定将数据存储在哪个分片上。这样可以实现数据的水平扩展,提高读写性能。

复制(Replication)

复制是指在多个节点之间复制和同步数据的过程。在复制中,有一个主节点(Primary)和多个从节点(Secondary)。主节点负责处理所有的写操作,并将写操作的结果复制到从节点。从节点复制主节点的数据,并可以用于读取操作。

复制提供了数据的冗余备份和高可用性。如果主节点发生故障,从节点可以自动选举出一个新的主节点来接管主节点的职责,确保系统的持续可用性。

分片和复制通常一起使用,以实现数据的水平扩展和高可用性。通过将数据分片存储在多个分片节点上,并使用复制来保证数据的冗余备份和故障转移,MongoDB可以提供可扩展性和可靠性。

20、数据在什么时候才会扩展到多个分片(shard)里?

数据在 MongoDB 中扩展到多个分片(shard)的时机是在创建或插入新数据时,根据指定的分片键(shard key)进行划分和分发。

在 MongoDB 中,分片键是用于决定数据在分片集群中如何分布的字段。当创建集合并定义了分片键后,MongoDB 将根据分片键的值将数据划分到相应的分片上。

当插入新数据时,MongoDB 将根据分片键的值确定数据应该分布在哪个分片上。如果数据的分片键值与已有分片不匹配,MongoDB 会自动创建新的分片,并将数据分发到新的分片上。这样,数据就会扩展到多个分片中。

需要注意的是,数据的分布和迁移是由 MongoDB 的分片路由器(mongos)自动管理的。分片路由器会根据分片键的值将读写请求路由到相应的分片上,以实现数据的水平扩展和负载均衡。

因此,数据在插入新数据并根据分片键进行分发时,才会扩展到多个分片中。

21、当我试图更新一个正在被迁移的块(chunk)上的文档时会发生什么?

当您试图更新一个正在被迁移的块(chunk)上的文档时,MongoDB 会根据具体情况采取以下行动:

  1. 如果更新操作涉及的文档位于源分片(source shard),并且迁移尚未完成,MongoDB 会将更新操作发送到源分片进行处理。源分片会执行更新操作并返回结果。

  2. 如果更新操作涉及的文档位于目标分片(target shard),并且迁移已经完成,MongoDB 会将更新操作发送到目标分片进行处理。目标分片会执行更新操作并返回结果。

  3. 如果更新操作涉及的文档既位于源分片又位于目标分片,并且迁移正在进行中,MongoDB 会根据具体情况采取不同的策略。可能的情况包括:

    • MongoDB 可能会将更新操作发送到源分片和目标分片的副本上进行处理,以确保数据的一致性。

    • MongoDB 可能会延迟更新操作,直到迁移完成后再执行。

需要注意的是,MongoDB 会自动处理正在进行的迁移和相关的更新操作,以确保数据的一致性和正确性。在迁移过程中,可能会出现一些延迟或性能下降,但 MongoDB 会尽力保证数据的完整性和可用性。

22、我怎么查看 Mongo正在使用的链接?

要查看 MongoDB 正在使用的连接,可以使用以下方法:

  1. 使用 MongoDB Shell:

    • 打开 MongoDB Shell。

    • 运行 db.currentOp() 命令来获取当前的操作信息。

    • 在返回的结果中,查找 connectionsactive 字段,可以看到当前的连接数和活动连接的详细信息。

  2. 使用 MongoDB 管理工具:

    • 使用 MongoDB 的官方管理工具,如 MongoDB Compass 或 MongoDB Atlas 控制台。

    • 在连接管理或监控部分,可以查看当前的连接数和活动连接的详细信息。

需要注意的是,具体的方法可能会因使用的 MongoDB 版本和部署方式而有所不同。如果使用的是 MongoDB 的分片集群或副本集,请确保在正确的节点上执行命令或查看连接信息。

另外,还可以使用 MongoDB 的性能监控工具或第三方工具来监视和分析连接的使用情况。这些工具可以提供更详细的连接统计和性能指标。

23、在MongoDb中如何添加索引?

在 MongoDB 中,可以使用 createIndex() 方法来添加索引。 createIndex() 方法用于在集合中创建一个新的索引。

以下是使用 createIndex() 方法添加索引的基本语法:

db.collection.createIndex({ field: 1 })

在上面的语法中, collection 是要添加索引的集合名称, field 是要创建索引的字段名称, 1 表示升序索引, -1 表示降序索引。

以下是一些常见的添加索引的示例:

1. 添加单字段索引:

db.users.createIndex({ username: 1 })

上述示例将在 users 集合中为 username 字段添加升序索引。

2. 添加多字段索引:

db.products.createIndex({ category: 1, price: -1 })

上述示例将在 products 集合中为 category 字段和 price 字段创建一个复合索引,其中 category 字段按升序排序, price 字段按降序排序。

3. 添加文本索引:

db.articles.createIndex({ content: "text" })

上述示例将在 articles 集合中为 content 字段创建一个文本索引,以支持全文搜索。

需要注意的是,添加索引可能会对写入性能产生一定的影响,因为每次插入、更新或删除操作时,MongoDB 都需要维护索引。因此,需要根据具体的使用场景和性能需求来选择适当的索引策略。

24、用什么方法可以格式化输出结果?

在 MongoDB 中,可以使用 pretty() 方法来格式化输出结果,使其更易读。

pretty() 方法可以应用于查询结果、聚合操作的输出以及其他命令的输出。它会将结果以更友好的格式进行缩进和换行,提高可读性。

以下是使用 pretty() 方法格式化输出结果的示例:

db.collection.find().pretty()

上述示例中, collection 是要查询的集合名称。通过在查询语句的末尾添加 .pretty() ,可以对查询结果进行格式化输出。

除了在查询中使用 pretty() 方法,还可以在聚合操作、命令输出等情况下使用。只需将相应的结果对象或命令添加 .pretty() 即可。

需要注意的是, pretty() 方法仅用于漂亮地显示结果,不会对结果进行任何更改或影响数据本身。

25、如何使用"AND"或"OR"条件循环查询集合中的文档?

在 MongoDB 中,可以使用 $and$or 条件操作符来执行 “AND” 和 “OR” 条件的查询。

使用 “$and” 进行 “AND” 查询:

可以使用 $and 操作符将多个条件组合在一起,以实现 “AND” 查询。下面是一个示例:

db.collection.find({
  $and: [
    { field1: value1 },
    { field2: value2 }
  ]
})

上述示例中, collection 是要查询的集合名称, field1field2 是要匹配的字段, value1value2 是要匹配的值。这个查询将返回同时满足 field1 等于 value1field2 等于 value2 的文档。

使用 “$or” 进行 “OR” 查询:

可以使用 $or 操作符将多个条件组合在一起,以实现 “OR” 查询。下面是一个示例:

db.collection.find({
  $or: [
    { field1: value1 },
    { field2: value2 }
  ]
})

上述示例中, collection 是要查询的集合名称, field1field2 是要匹配的字段, value1value2 是要匹配的值。这个查询将返回满足 field1 等于 value1field2 等于 value2 的文档。

需要注意的是,可以在查询中使用多个 $and$or 操作符,以便更复杂的条件组合。同时,还可以与其他查询操作符一起使用,以实现更灵活的查询条件。

26、在MongoDB中如何更新数据?

在 MongoDB 中,可以使用 update() 方法或 updateOne() 方法来更新数据。

update() 方法用于更新符合指定条件的多个文档,而 updateOne() 方法用于更新符合指定条件的单个文档。

以下是使用 update() 方法更新数据的示例:

db.collection.update(
  { field1: value1 }, // 更新条件
  { $set: { field2: value2 } }, // 更新操作
  { multi: true } // 更新多个文档
)

上述示例中, collection 是要更新的集合名称, field1 是要匹配的字段, value1 是要匹配的值。 $set 操作符用于指定要更新的字段和值, field2 是要更新的字段, value2 是要更新的值。 multi: true 表示更新所有符合条件的文档。

以下是使用 updateOne() 方法更新数据的示例:

db.collection.updateOne(
  { field1: value1 }, // 更新条件
  { $set: { field2: value2 } } // 更新操作
)

上述示例中, collection 是要更新的集合名称, field1 是要匹配的字段, value1 是要匹配的值。 $set 操作符用于指定要更新的字段和值, field2 是要更新的字段, value2 是要更新的值。 updateOne() 方法只会更新第一个符合条件的文档。

需要注意的是,以上示例中的更新操作是替换整个文档,如果只需要更新文档中的特定字段,可以使用其他操作符,如 $set$unset$inc 等。详细的更新操作符可以参考 MongoDB 的官方文档。

27、如何删除文档?

在 MongoDB 中,可以使用 deleteOne() 方法或 deleteMany() 方法来删除文档。

deleteOne() 方法用于删除符合指定条件的单个文档,而 deleteMany() 方法用于删除符合指定条件的多个文档。

以下是使用 deleteOne() 方法删除文档的示例:

db.collection.deleteOne({ field1: value1 }) // 删除条件

上述示例中, collection 是要删除文档的集合名称, field1 是要匹配的字段, value1 是要匹配的值。 deleteOne() 方法只会删除第一个符合条件的文档。

以下是使用 deleteMany() 方法删除文档的示例:

db.collection.deleteMany({ field1: value1 }) // 删除条件

上述示例中, collection 是要删除文档的集合名称, field1 是要匹配的字段, value1 是要匹配的值。 deleteMany() 方法会删除所有符合条件的文档。

需要注意的是,删除操作会永久性地从数据库中删除文档,因此在执行删除操作之前,请确保已经确认要删除的文档。

28、在MongoDB中如何排序?

在 MongoDB 中,可以使用 sort() 方法对查询结果进行排序。

sort() 方法接受一个排序规则作为参数,用于指定按照哪个字段进行排序以及排序的顺序。

以下是使用 sort() 方法对查询结果进行排序的示例:

db.collection.find().sort({ field1: 1, field2: -1 })

上述示例中, collection 是要查询的集合名称, field1field2 是要排序的字段。数字 1 表示升序排序,-1 表示降序排序。

如果只想根据单个字段进行排序,可以简化为:

db.collection.find().sort({ field1: 1 })

需要注意的是,排序操作会对查询结果进行重排,因此可能会影响查询的性能。为了提高查询性能,可以在查询语句中使用索引来加速排序操作。

另外,还可以使用 limit() 方法限制查询结果的数量,以便在排序后只返回前几个结果:

db.collection.find().sort({ field1: 1 }).limit(10)

上述示例中, limit(10) 限制了查询结果只返回前 10 条文档。

29、什么是聚合?

聚合(Aggregation)是 MongoDB 中用于处理数据的强大功能。它允许您根据指定的条件对集合中的文档进行分组、筛选、计算和转换,以生成更有意义的结果。

聚合操作可以用于执行各种数据处理任务,例如统计数据、生成报表、计算平均值、求和、分组统计等。它提供了一种灵活的方式来处理和分析大量数据,并从中提取有价值的信息。

MongoDB 的聚合框架提供了一个管道(Pipeline)的概念,通过将多个聚合操作按顺序连接起来,逐步处理数据。聚合管道由一系列聚合阶段(Aggregation Stage)组成,每个阶段都执行特定的操作,将处理结果传递给下一个阶段。

常用的聚合操作包括:

  • $match :用于筛选符合指定条件的文档。

  • $group :用于按照指定字段对文档进行分组。

  • $project :用于选择和重命名字段,以及计算新的字段。

  • $sort :用于对文档进行排序。

  • $limit :用于限制返回结果的文档数量。

  • $skip :用于跳过指定数量的文档。

聚合操作还可以使用各种内置的聚合函数(Aggregation Functions),如 $sum$avg$min$max 等,用于计算字段的聚合值。

需要注意的是,聚合操作可以在单个集合上执行,也可以在多个集合之间进行联合聚合。它提供了灵活且强大的数据处理能力,使您能够根据具体需求对数据进行深入分析和处理。

30、在MongoDB中什么是副本集?

在 MongoDB 中,副本集(Replica Set)是一组运行在不同服务器上的 MongoDB 实例的集合。副本集用于提供数据冗余备份和高可用性。

副本集通常由一个主节点(Primary)和多个从节点(Secondary)组成。主节点负责处理所有的写操作,并将写操作的结果复制到从节点。从节点复制主节点的数据,并可以用于读取操作。

副本集的主要目标是提供数据的冗余备份和故障转移。如果主节点发生故障或不可用,副本集会自动从从节点中选举出一个新的主节点来接管主节点的职责,确保系统的持续可用性。

副本集还具有其他功能,如自动故障检测和自动恢复,以及支持读操作的可扩展性。通过在多个服务器上运行副本集的成员,可以提高读取性能和负载均衡。

副本集的配置和管理由 MongoDB 的副本集协调器(Replica Set Coordinator)负责。副本集协调器监视副本集的状态,并确保数据的一致性和可用性。

需要注意的是,副本集在 MongoDB 中是一种高可用性和冗余备份的解决方案,不同于分片(Sharding),后者用于水平扩展和处理大规模数据。

一文读懂MongoDB的知识点(2),惊呆面试官。_第2张图片

你可能感兴趣的:(Redis专栏,MySQL专栏,数据库专栏,mongodb,数据库,面试,职场和发展,database,intellij,idea)