MongoJS无法通过ID删除文档问题排查求助
MongoDB删除失败问题排查与修复
嘿,我仔细看了你的代码和测试场景,发现两个核心问题导致deleteRecipeById无法正常工作,咱们拆解来看:
1. _id类型不匹配(最根本的原因)
你的mock数据里_id是数字类型(比如0、1),但你在deleteRecipeById里把传入的recipeId强制转换成了ObjectId:
var recipeIdAsObject = new ObjectId(recipeId); var result = recipeCollection.deleteMany({"_id":recipeIdAsObject});
MongoDB的查询是严格匹配数据类型的——数字0和ObjectId类型的0完全是两个不同的值,这个查询条件根本找不到你要删除的文档,自然删不掉。
你可以通过getRecipeById的打印输出验证这一点:如果打印出的文档_id是数字,就说明数据库里存的确实是数字类型,不是ObjectId。
2. 异步操作未等待,提前关闭连接
deleteMany是异步函数,你没有加await就直接调用client.close(),这会导致数据库连接在删除操作完成前就被关闭,操作可能还没执行完就被终止了。
修复后的完整函数代码
把这两个问题都修正后,deleteRecipeById应该改成这样:
async deleteRecipeById(recipeId){ try{ const client = new MongoClient(this.uriString); await client.connect(); const db = client.db(this.databaseString); const recipeCollection = db.collection(this.collectionString); // 直接使用传入的数字类型ID,不需要转换为ObjectId var result = await recipeCollection.deleteMany({"_id": recipeId}); // 等待删除操作完成后再关闭客户端连接 await client.close(); return result; } catch(e){ console.error(e); throw e; // 记得抛出错误,让调用方能够捕获并处理 } }
额外的优化建议
- 避免每次操作都创建新的MongoClient连接:MongoDB驱动本身会维护连接池,重复创建连接会影响性能,建议把Client的初始化放到类的构造函数中,复用连接。
- 简化测试代码的Promise嵌套:改成async/await写法,避免回调地狱,代码可读性更高:
describe('Testing delete Recipe',()=>{ it('1. Delete known recipe', async ()=>{ var uri = "mongodb://localhost:27017"; var dbname = "testRecipes"; var collectionName = "testCollectionMessy"; let driver = new MongoDriver(uri,dbname,collectionName); await driver.dropCollection(); await driver.addMockData(); const targetRecipe = await driver.getRecipeById(mockData[0]._id); console.log(targetRecipe); const deleteResult = await driver.deleteRecipeById(0); console.log(deleteResult); console.log(mockData[0]._id); assert.deepEqual(deleteResult.deletedCount,1); }) })
内容的提问来源于stack exchange,提问作者jakegergen
相关产品推荐
相关产品推荐

