2016-11-24 28 views
1

更新工作: 本身具有手动提供参数运行getSections功能似乎正常工作。在打印出导致错误的参数,它的每一次是一组不同的...MongoDB的“无法连接到服务器”的错误,尽管相同的连接以前


我有一个调用它里面的几个不同功能的updateCurrentTerm()函数,所有这些更新不同的收藏相同的数据库。每一种使完全相同的方式到数据库的连接,因为这样的:

MongoClient.connect(MONGOURL + term, (err, db) => { 

哪里MONGOURL'mongodb://localhost:27017/'term'4650'。但是,连接似乎适用于getSchools,getSubjects,getCourses,但不是getSections。下面是完整的错误我得到:

TypeError: Cannot read property 'collection' of null 
    at /Users/Joon/sans/app.js:129:26 
    at connectCallback (/Users/Joon/sans/node_modules/mongodb/lib/mongo_client.js:315:5) 
    at /Users/Joon/sans/node_modules/mongodb/lib/mongo_client.js:222:11 
    at _combinedTickCallback (internal/process/next_tick.js:67:7) 
    at process._tickCallback (internal/process/next_tick.js:98:9) 

我进一步研究:在MongoClient.connect回调是空意味着犯错参数是不是空的数据库参数。 err参数包含:

{ MongoError: failed to connect to server [localhost:27017] on first connect 
    at .<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/topologies/server.js:313:35) 
    at emitOne (events.js:96:13) 
    at emit (events.js:188:7) 
    at .<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/connection/pool.js:271:12) 
    at g (events.js:286:16) 
    at emitTwo (events.js:106:13) 
    at emit (events.js:191:7) 
    at Socket.<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/connection/connection.js:165:49) 
    at Socket.g (events.js:286:16) 
    at emitOne (events.js:96:13) 
    name: 'MongoError', 
    message: 'failed to connect to server [localhost:27017] on first connect' } 

任何帮助将不胜感激。谢谢!


app.js

import { MongoClient } from 'mongodb'; 
import request from 'request-json'; 
import { EventEmitter } from 'events'; 

const API = request.createClient('http://www.northwestern.edu/class-descriptions/'); 
const MONGOURL = 'mongodb://localhost:27017/'; 
const EVENT = new EventEmitter(); 


const makeRequest = (query, type, callback) => { 
    // Possible types: 
    // terms 
    // schools 
    // subjects 
    // courses 
    // sections 
    // details 

    // Prepare query with correct ending 
    if (type === 'terms') { 
     query = 'index-v2.json'; 
    } else if (type === 'details') { 
     query += '-v2.json'; 
    } else { 
     query += '/index-v2.json'; 
    } 

    API.get(query, (err, response, body) => { 
     if (err) { 
      console.log(err); 

      callback(null, err); 
     } else { 
      // Parse out last non-data term 
      const last = body[body.length - 1]; 
      const lastKeys = Object.keys(last); 
      if (lastKeys.length === 1 && lastKeys[0] === 'ignore') { 
       body.pop(); 
      } 

      callback(body, null); 
     } 
    }); 
} 

const getTerms = (callback) => { 
    // TODO: Refactor to insert only if new term 
    MongoClient.connect(MONGOURL + 'terms', (err, db) => { 
     const coll = db.collection('data'); 
     coll.remove(); // Start clean 
     makeRequest('', 'terms', (data, err) => { 
      if (!err) { 
       coll.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getSchools = (term, callback) => { 
    // term is the term id (not the mongodb _id) 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     const schools = db.collection('schools'); 
     makeRequest(term, 'schools', (data, err) => { 
      if (!err) { 
       schools.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getSubjects = (term, school, callback) => { 
    // term is the term id (not the mongodb _id) 
    // school is the school id (not the mongodb _id) 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     const subjects = db.collection('subjects'); 

     const query = term + '/' + school; 
     makeRequest(query, 'subjects', (data, err) => { 
      if (!err) { 
       subjects.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getCourses = (term, school, subject, callback) => { 
    // term is the term id (not the mongodb _id) 
    // school is the school id (not the mongodb _id) 
    // subject is the subject abbv 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     const courses = db.collection('courses'); 

     const query = term + '/' + school + '/' + subject; 
     makeRequest(query, 'courses', (data, err) => { 
      if (!err) { 
       courses.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getSections = (term, school, subject, course, callback) => { 
    // term is the term id (not the mongodb _id) 
    // school is the school id (not the mongodb _id) 
    // subject is the subject abbv 
    // course is the course abbv 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     console.log(err); 
     const sections = db.collection('sections'); 

     const query = term + '/' + school + '/' + subject + '/' + course; 
     makeRequest(query, 'sections', (data, err) => { 
      if (!err) { 
       sections.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getDetails = (term, school, subject, course, section, callback) => { 
    // term is the term id (not the mongodb _id) 
    // school is the school id (not the mongodb _id) 
    // subject is the subject abbv 
    // course is the course abbv 
    // section is the section id (not the mongodb _id) 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     const details = db.collection('details'); 

     const query = term + '/' + school + '/' + subject + '/' + course + '/' + section; 
     makeRequest(query, 'details', (data, err) => { 
      if (!err) { 
       details.insertMany(data, (err, result) => { 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const updateCurrentTerm =() => { 
    MongoClient.connect(MONGOURL + 'terms', (err, db) => { 
     const terms = db.collection('data'); 
     // Find term with max id (not mongodb _id) 
     terms.find().sort({id:-1}).limit(1).next((err, doc) => { 
      EVENT.emit('maxTerm', doc.id); 
      db.close(); 
     }); 
    }); 

    EVENT.on('maxTerm', (term) => { 
     MongoClient.connect(MONGOURL + term, (err, db) => { 
      db.collection('schools').remove(); 
      db.collection('subjects').remove(); 
      db.collection('courses').remove(); 
      db.collection('sections').remove(); 
      db.collection('details').remove(); 
      db.close(); 
      EVENT.emit('clean', term); 
     }); 
    }); 

    EVENT.on('clean', (term) => { 
     getSchools(term, (data) => { 
      EVENT.emit('updatedSchools', term, data); 
     }); 
    }); 

    EVENT.on('updatedSchools', (term, data) => { 
     data.forEach((school) => { 
      getSubjects(term, school.id, (newData) => { 
       EVENT.emit('updatedSubjects', term, school.id, newData); 
      }); 
     }); 
    }); 

    EVENT.on('updatedSubjects', (term, school, data) => { 
     data.forEach((subject) => { 
      getCourses(term, school, subject.abbv, (newData) => { 
       EVENT.emit('updatedCourses', term, school, subject.abbv, newData); 
      }); 
     }); 
    }); 

    EVENT.on('updatedCourses', (term, school, subject, data) => { 
     data.forEach((course) => { 
      getSections(term, school, subject, course.abbv, (newData) => { 
       EVENT.emit('updatedSections', term, school, subject, course.abbv, newData); 
      }); 
     }); 
    }); 
} 

updateCurrentTerm(); 
+0

你能分享你的mongod日志吗? –

+0

这里是一个开始mongod然后运行app.js一次的日志:https://gist.github.com/Joonpark13/e815c260820db9343f3c7f0909d39c2c –

+0

你检查过'getSchools','getSubjects','getCourses',getSections '什么时候updateCurrentTerm()'?它应该是一样的,对吧? –

回答

1

你正在运行一个查询每一次,你要创建一个新的实例,它是太多的连接到您的mongod!这是行不通的,因为每个实例都会创建并保持至少一个连接(但默认情况下为10),并且只有在Java GC清理Mongo实例或调用close()时,才会删除这些连接。

创建到Mongo的新连接非常昂贵,它也会降低您的mongod性能。所以创建一个Mongo实例并尽可能长时间保持活跃状态​​!用一个静态方法实现一个MongoFactory getInstance()返回一个懒惰创建的实例将会很好的解决这个问题。

+0

我最终重构了我的代码,总共有很多,更少的连接,而且现在它似乎只能处理很少的错误。谢谢! –

相关问题