Mongoose中findById返回null但find正常的技术问题求助
findById Returns Null But find() Fetches the Document Hey there, let's break down why your updateCourse function can't find the target document with findById, while getCourses works perfectly with find(). Given your tech stack (Mongoose ^5.0.1, Node.js v8.9.4, MongoDB 4.2.6 Community), here are the most likely culprits and fixes:
1. ObjectId String-to-Object Conversion Glitch
MongoDB stores _id as an ObjectId type, not a plain string. While Mongoose usually auto-converts string IDs to ObjectId, older versions like 5.0.1 sometimes fail at this silently. That’s probably why findById can’t match your string ID to the stored ObjectId.
Fix it manually:
Explicitly convert the string ID to an ObjectId before querying:
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/mongo-exercises') .then(()=>{ console.log('DataBase Connected..!!'); }) .catch(err=> console.log('Connection err: ',err)); const schema = new mongoose.Schema({ tags:[ String ], date:Date, name: String, author: String, isPublished: Boolean, price: Number }); const Course = mongoose.model('course',schema); async function updateCourse(id){ // Convert string ID to ObjectId const objectId = mongoose.Types.ObjectId(id); const course = await Course.findById(objectId); if(!course) { console.log("No document found with that ID"); return; } course.name = "mongo db"; console.log(course) const result = await course.save(); } updateCourse("5a68fdc3615eda645bc6bdec");
2. Collection Name Mismatch
Mongoose automatically pluralizes and lowercases your model name to get the collection name. Since your model is named course, Mongoose will look for a collection named courses (plural). But if your actual MongoDB collection is named course (singular), this mismatch could cause findById to fail while find() might still work due to looser matching in some cases.
Check & fix:
- Run
show collectionsin your MongoDB shell to confirm the collection name. - If it’s
course(singular), explicitly specify the collection name when creating the model:
// Third argument forces Mongoose to use the exact collection name const Course = mongoose.model('course', schema, 'course');
3. Model Registration Timing Issue
In early Mongoose 5.x versions, there’s a rare race condition where models are defined before the database connection is fully established. Even though you’re using async/await, the findById query might execute before the model is properly registered.
Fix by delaying model setup:
Move your model definition and function calls inside the connection success callback:
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/mongo-exercises') .then(()=>{ console.log('DataBase Connected..!!'); // Define model only after connection is ready const schema = new mongoose.Schema({ tags:[ String ], date:Date, name: String, author: String, isPublished: Boolean, price: Number }); const Course = mongoose.model('course',schema); async function updateCourse(id){ const course = await Course.findById(id); if(!course) return; course.name = "mongo db"; console.log(course) const result = await course.save(); } updateCourse("5a68fdc3615eda645bc6bdec"); }) .catch(err=> console.log('Connection err: ',err));
4. Verify ID Match
Double-check that the ID you’re passing actually matches the stored document’s _id. Add this check to your getCourses function to confirm:
async function getCourses(){ const result = await Course.find(); console.log(result); // Compare your target ID to each document's stringified _id const targetId = "5a68fdc3615eda645bc6bdec"; const matchedDoc = result.find(doc => doc._id.toString() === targetId); console.log("Matched document:", matchedDoc); }
Start with the first fix (manual ObjectId conversion)—that’s the most common issue with older Mongoose versions. Let me know if any of these work for you!
内容的提问来源于stack exchange,提问作者Divay Mohan

