一、概念理解类
1. 什么是MongoDB?
答案:MongoDB是由C++语言编写的基于分布式文件存储的开源数据库系统,旨在为Web应用提供可扩展、高性能的数据存储解决方案。它将数据存储为文档,数据结构由键值对组成,类似JSON对象,字段值可包含其他文档、数组及文档数组。
2. NoSQL数据库是什么意思?NoSQL与RDBMS有什么区别?为什么要使用和不使用NoSQL数据库?
答案:NoSQL是非关系型数据库,NoSQL=Not Only SQL。关系型数据库采用结构化的数据存储方式,NoSQL则采用键值对存储数据。在处理非结构化/半结构化大数据、水平扩展、应对动态增加的数据项时优先考虑NoSQL数据库;考虑数据库成熟度、支持、分析商业智能、管理专业性等问题时优先考虑关系型数据库。
3. MySQL与MongoDB之间最基本的差别是什么?
答案:两者都是免费开源数据库,但数据的表示、查询、关系、事务、模式设计和定义、标准化、速度和性能等方面存在基本差别,本质上是关系型和非关系型数据库数据存储结构不同。
4. 你怎么比较MongoDB、CouchDB及CouchBase?
答案:它们都是面向文档的数据库,除都以文档形式存储外无其他共同点,在数据模型实现、接口、对象存储以及复制方法等方面有很多不同。
5. MongoDB成为最好的NoSQL数据库的原因是什么?
答案:具有面向文件、高性能、高可用性、易扩展性、丰富查询语言等特点。
6. journal回放在条目(entry)不完整时会遇到问题吗?
答案:每个journal (group)的写操作都是一致的,除非它是完整的否则在恢复过程中不会回放。
7. 分析器在MongoDB中的作用是什么?
答案:可以显示数据库中每个操作的性能特点,通过它能找到比预期慢的查询或写操作,从而确定是否需要添加索引。
8. 名字空间(namespace)是什么?
答案:MongoDB存储BSON对象在集合中,数据库名字和集合名字以句点连结起来就是名字空间。
9. 如果用户移除对象的属性,该属性是否从存储层中删除?
答案:是的,用户移除属性后对象会重新保存。
二、操作类
11. 允许空值null吗?
答案:对于对象成员而言,是的。但不能添加空值到数据库集合,不过可以添加空对象{}。
12. 更新操作立刻fsync到磁盘吗?
答案:不会,磁盘写操作默认是延迟执行的,可能在两三秒后到达磁盘。
13. 如何执行事务/加锁?
答案:MongoDB没有使用传统的锁或者复杂的带回滚的事务,设计宗旨是轻量、快速及可预计的高性能,可类比成MySQLMylSAM的自动提交模式,通过精简对事务的支持提升性能。
14. 我必须调用getLastError来确保写操作生效了吗?
答案:不用,不管是否调用getLastError(又叫“Safe Mode”),服务器做的操作都一样。
15. 如何创建一个新的集合?
答案:使用db.createCollection("集合名称")
命令可以创建一个新的集合。
16. 如何在集合中插入文档?
答案:使用db.集合名称.insertOne()
或db.集合名称.insertMany()
方法可以插入单个或多个文档。例如:db.students.insertOne({"name": "John", "age": 20})
。
17. 如何查询集合中的文档?
答案:使用db.集合名称.find()
方法可以根据指定条件查询文档。例如:db.students.find({"age": {$gt: 18}})
查询年龄大于18的学生。
18. 如何更新集合中的文档?
答案:使用db.集合名称.updateOne()
或db.集合名称.updateMany()
方法可以更新单个或多个文档。例如:db.students.updateOne({"name": "John"}, {$set: {"age": 21}})
将名为John的学生年龄更新为21。
19. 如何删除集合中的文档?
答案:使用db.集合名称.deleteOne()
或db.集合名称.deleteMany()
方法可以删除单个或多个文档。例如:db.students.deleteOne({"name": "John"})
删除名为John的学生。
20. 如何对查询结果进行排序?
答案:在find()
方法中使用sort()
方法进行排序。例如:db.students.find().sort({"age": -1})
按照年龄降序排序。
三、索引类
21. 什么是索引?在MongoDB中如何创建索引?
答案:索引是一种特殊的数据结构,用于加速数据库的查询操作。在MongoDB中,可以使用db.集合名称.createIndex()
方法创建索引。例如:db.students.createIndex({"name": 1})
在“name”字段上创建升序索引。
22. 如何查看集合上的索引?
答案:使用db.集合名称.getIndexes()
方法可以查看集合上的所有索引。
23. 如何删除集合上的索引?
答案:使用db.集合名称.dropIndex()
方法可以删除指定的索引。例如:db.students.dropIndex("name_index")
删除“name”字段上的索引。
24. 什么是文本索引?如何在MongoDB中创建文本索引?
答案:文本索引用于在字符串字段上进行高效的文本搜索。在MongoDB中,可以使用db.集合名称.createIndex({"字段名": "text"})
创建文本索引。例如:db.articles.createIndex({"content": "text"})
在“content”字段上创建文本索引。
25. 什么是唯一索引?如何在MongoDB中创建唯一索引?
答案:唯一索引确保字段中的值是唯一的。在MongoDB中,可以使用db.集合名称.createIndex({"字段名": 1}, {unique: true})
创建唯一索引。例如:db.users.createIndex({"email": 1}, {unique: true})
在“email”字段上创建唯一索引。
四、聚合类
26. 什么是聚合框架?在MongoDB中如何使用聚合框架?
答案:聚合框架提供了一组强大的操作符,用于对数据集进行复杂的数据处理和分析。在MongoDB中,使用`db.集合名称.aggregate()`方法可以进行聚合操作。例如:`db.orders.aggregate([{$group: {_id: "$customerId", total: {$sum: "$amount"} }])`按客户分组并计算订单总金额。
27. 如何在聚合中使用匹配阶段($match)?
答案:在聚合管道的第一个阶段使用$match
,用于过滤文档。例如:db.orders.aggregate([{$match: {"status": "shipped"}}, ...])
只处理已发货的订单。
28. 如何在聚合中使用分组阶段($group)?
答案:使用$group
阶段对文档进行分组,并根据指定的字段进行汇总计算。例如:db.orders.aggregate([{$group: {_id: "$productId", quantity: {$sum: 1}}}])
按产品分组并计算每个产品的订单数量。
29. 如何在聚合中使用投影阶段($project)?
答案:使用$project
阶段选择要包含在结果中的字段,也可以进行字段重命名和计算。例如:db.orders.aggregate([{$project: {"productName": "$product.name", "totalAmount": 1}}])
只返回产品名称和订单总金额。
30. 如何在聚合中使用排序阶段($sort)?
答案:在聚合管道中使用$sort
阶段对结果进行排序。例如:db.orders.aggregate([{$sort: {"totalAmount": -1}}])
按订单总金额降序排序。