面试题答案
一键面试- 重复键异常
- 异常描述:在插入文档时,如果文档中的某个字段被定义为唯一索引,而插入的文档该字段值与已有文档冲突,就会抛出重复键异常。
- 处理方式:
- 在插入前,先使用
findOne
方法查询该键值是否已存在,若存在则不进行插入操作,或者更新已有文档。例如,假设users
集合中email
字段是唯一索引,在插入新用户前:
- 在插入前,先使用
const user = {email: "test@example.com", name: "John"};
const existingUser = db.users.findOne({email: user.email});
if (!existingUser) {
db.users.insertOne(user);
}
- 连接异常
- 异常描述:当无法连接到MongoDB服务器时,会出现连接异常。这可能由于服务器地址错误、端口未开放、服务器未启动等原因导致。
- 处理方式:
- 检查MongoDB服务器是否已启动,使用
mongo
命令行工具尝试连接。如果服务器未启动,启动服务器。 - 确认连接字符串是否正确,检查主机地址、端口号等信息。例如,在Node.js中使用
mongoose
连接MongoDB:
- 检查MongoDB服务器是否已启动,使用
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mydb', {
useNewUrlParser: true,
useUnifiedTopology: true
}).catch((error) => {
console.error('连接异常:', error.message);
// 可以在这里进行重试逻辑,比如使用setTimeout定期重试
});
- 类型不匹配异常
- 异常描述:在更新文档或插入文档时,如果提供的数据类型与集合定义的模式(如果有定义模式的话)不匹配,会出现类型不匹配异常。例如,试图将字符串类型的值插入到定义为数字类型的字段中。
- 处理方式:
- 在插入或更新数据前,对数据进行类型检查和转换。例如,假设要向
products
集合插入数据,其中price
字段应为数字类型:
- 在插入或更新数据前,对数据进行类型检查和转换。例如,假设要向
const product = {name: "Widget", price: "100"};
product.price = parseFloat(product.price);
if (isNaN(product.price)) {
console.error('价格数据类型错误');
} else {
db.products.insertOne(product);
}
- 文档不存在异常(删除或更新时)
- 异常描述:在执行删除或更新操作时,如果根据指定条件找不到对应的文档,可能会导致逻辑上的“文档不存在异常”,虽然MongoDB本身不会抛出严格意义上的异常,但可能不符合业务预期。
- 处理方式:
- 在删除或更新前,先使用
findOne
方法检查文档是否存在。例如,要删除orders
集合中某个订单:
- 在删除或更新前,先使用
const orderId = ObjectId("5f9d8f5a2795954a3c852911");
const existingOrder = db.orders.findOne({_id: orderId});
if (existingOrder) {
db.orders.deleteOne({_id: orderId});
} else {
console.error('订单不存在');
}
- 查询语法错误异常
- 异常描述:当编写的查询语句不符合MongoDB的查询语法规则时,会出现查询语法错误异常。例如,使用了错误的操作符或者操作符位置错误。
- 处理方式:
- 仔细检查查询语句的语法,参考MongoDB官方文档中的查询语法说明。例如,查询
users
集合中年龄大于30岁的用户,正确语法如下:
- 仔细检查查询语句的语法,参考MongoDB官方文档中的查询语法说明。例如,查询
db.users.find({age: {$gt: 30}});
如果写成db.users.find({age: {gt: 30}})
就会报错,因为缺少$
符号,需要修正为正确的语法。