Node.js应用TypeError报错排查:MongoDB旧代码运行异常
Fixing the "Cannot read property 'visits' of undefined" Error in Your MongoDB Code
Let's walk through exactly why this error is happening and update the outdated code to work with modern MongoDB drivers:
Key Issues in the Original Code
1. Mismatched Query Value (The Direct Cause of the Error)
When you insert the website object, its url is set to 'http://www.google.com'. But your findKey uses { url: 'www.google.com' } — these two strings don't match at all! So when you run collection.find(findKey).toArray(), the results array comes back empty, and trying to access results[0].visits throws the TypeError because results[0] is undefined.
2. Outdated MongoDB Driver Methods
Your textbook's code uses old driver methods that have been deprecated for years:
collection.insert()→ replaced withinsertOne()/insertMany()(more explicit about what you're inserting)collection.update()→ replaced withupdateOne()/updateMany()(prevents accidental bulk updates)
These old methods might behave unpredictably with newer driver versions.
Fixed Code (Updated for Modern MongoDB Drivers)
const MongoClient = require('mongodb').MongoClient; const website = { url: 'http://www.google.com', visits: 0 }; const findKey = { url: 'http://www.google.com' }; // Fixed the URL to match the inserted one MongoClient.connect('mongodb://127.0.0.1:27017/demo', { useNewUrlParser: true }, function(err, client) { if (err) throw err; const db = client.db('demo'); const collection = db.collection('websites'); // Use insertOne instead of the deprecated insert method collection.insertOne(website, function(err, docs) { if (err) { console.error('Insert error:', err); client.close(); return; } let done = 0; const totalUpdates = 4; function onDone(err) { if (err) { console.error('Update error:', err); // Even if one update fails, we still want to clean up done = totalUpdates; } done++; if (done < totalUpdates) return; // Add a check for empty results before accessing properties collection.find(findKey).toArray(function(err, results) { if (err) { console.error('Find error:', err); } else if (results.length === 0) { console.log('No document found matching the query'); } else { console.log('Visits:', results[0].visits); } // Cleanup collection.drop(function() { client.close(); }); }); } const incrementVisits = { '$inc': { 'visits': 1 } }; // Use updateOne instead of the deprecated update method collection.updateOne(findKey, incrementVisits, onDone); collection.updateOne(findKey, incrementVisits, onDone); collection.updateOne(findKey, incrementVisits, onDone); collection.updateOne(findKey, incrementVisits, onDone); }); });
What Changed?
- Fixed the
findKeyURL to exactly match the one inserted - Swapped deprecated
insert/updatemethods for moderninsertOne/updateOne - Added error handling for each database operation to catch issues early
- Added a check for empty
resultsbefore trying to accessresults[0].visits - Made the update count explicit for better readability
If you want to use async/await (the preferred style now for Node.js), here's an even cleaner version:
const MongoClient = require('mongodb').MongoClient; async function run() { const client = await MongoClient.connect('mongodb://127.0.0.1:27017/demo', { useNewUrlParser: true }); try { const db = client.db('demo'); const collection = db.collection('websites'); const website = { url: 'http://www.google.com', visits: 0 }; const findKey = { url: 'http://www.google.com' }; const incrementVisits = { '$inc': { 'visits': 1 } }; await collection.insertOne(website); // Run all 4 updates in parallel await Promise.all([ collection.updateOne(findKey, incrementVisits), collection.updateOne(findKey, incrementVisits), collection.updateOne(findKey, incrementVisits), collection.updateOne(findKey, incrementVisits) ]); const results = await collection.find(findKey).toArray(); if (results.length > 0) { console.log('Visits:', results[0].visits); // Should log 4 } else { console.log('No document found'); } await collection.drop(); } catch (err) { console.error('Error:', err); } finally { await client.close(); } } run();
内容的提问来源于stack exchange,提问作者runnerpaul
相关产品推荐
相关产品推荐

