我想要做的是,在.txt文件中读取,在换行符处切换它们,然后对于构造数组中的每个单词,对单词执行操作(与Word Schema I&匹配) #39; m使用)确定每个单词的字母数,例如"单词(0 A' s,0 B' s,1 W,1 O,1 R,1 D,O Z& #39; s等...),然后将每个Word插入数据库。
这是Word"形状"的猫鼬模式。对于数据库条目(models / words.js)
var restful = require('node-restful');
var mongoose = restful.mongoose;
// MongoDB Schema
var wordSchema = new mongoose.Schema({
code: String,
word: String,
lettersCount: {
'a': Number,
'b': Number,
'c': Number,
'd': Number,
'e': Number,
'f': Number,
'g': Number,
'h': Number,
'i': Number,
'j': Number,
'k': Number,
'l': Number,
'm': Number,
'n': Number,
'o': Number,
'p': Number,
'q': Number,
'r': Number,
's': Number,
't': Number,
'u': Number,
'v': Number,
'w': Number,
'x': Number,
'y': Number,
'z': Number
}
});
// Return model
module.exports = restful.model(
'Words',
wordSchema
);
现在,我的数据位于文件dictionaries/words.txt
。
在名为server.js
的主文件中,我正在调用此函数:
populateDictionary();
tasks/populateDictionary.js
文件具有以下函数来执行数据库条目:
var populateDictionary = function(dict) {
Word.remove().exec();
fs.readFileAsync('dictionaries/words.txt', 'utf8').then(function(data, err) {
if (err) throw err;
var dictionary = data.split('\n');
for (var i = 0; i < dictionary.length; i++) {
var entry = new Word({
word: dictionary[i],
lettersCount: {
'a': 0, 'b': 0, 'c': 0, 'd': 0,
'e': 0, 'f': 0, 'g': 0, 'h': 0,
'i': 0, 'j': 0, 'k': 0, 'l': 0,
'm': 0, 'n': 0, 'o': 0, 'p': 0,
'q': 0, 'r': 0, 's': 0, 't': 0,
'u': 0, 'v': 0, 'w': 0, 'x': 0,
'y': 0, 'z': 0
}
});
for (var j = 0; j < entry.word.length; j++) {
entry.lettersCount[entry.word[j]]++;
}
console.log(entry);
entry.save();
}
});
};
所以,我对数据库还是比较陌生的,但是认为那里有一个很好的解决方案,只是不确定是什么......我基本上是在制作一个庞大的调用堆栈,而且它& #39;崩溃了我的电脑。我正在寻找做这种事情的正确方法。谢谢!
答案 0 :(得分:2)
我建议使用async库。它有许多有用的方法。我在下面使用async.eachLimit将异步操作限制为所提供的数字。
clearDictionary(function(err){
if(err){
throw err;
}
else{
populateDictionary();
}
})
由于remove
也是一个io调用,因此它应该在操作结束之前等待,然后再转到下一部分。这就是为什么包裹在上面的clearDictionary
。定义如下:
var async = require("async");
var clearDictionary = funtion(done) {
Word.remove().exec(function(err){
if(err){
done(err);
}
else{
done();
}
});
}
var populateDictionary = function() {
fs.readFileAsync('dictionaries/words.txt', 'utf8').then(function(data, err) {
if (err) throw err;
var dictionary = data.split('\n');
async.eachLimit(dictionary, 20, funtion(word, callback){
var entry = new Word({
word: word,
lettersCount: getLetterCountObj()
});
countLetters(entry);
entry.save(function(err){
if(err){
return callback(err);
}
else{
return callback();
}
});
}, function(err){
if(err){
throw err
}
else{
console.log("Dictionary populated!");
}
})
});
};
var getLetterCountObj = function(){
return {
'a': 0, 'b': 0, 'c': 0, 'd': 0,
'e': 0, 'f': 0, 'g': 0, 'h': 0,
'i': 0, 'j': 0, 'k': 0, 'l': 0,
'm': 0, 'n': 0, 'o': 0, 'p': 0,
'q': 0, 'r': 0, 's': 0, 't': 0,
'u': 0, 'v': 0, 'w': 0, 'x': 0,
'y': 0, 'z': 0
}
}
var countLetters = function (entry){
for (var j = 0; j < entry.word.length; j++) {
entry.lettersCount[entry.word[j]]++;
}
}
答案 1 :(得分:0)
我对您使用的确切技术不是很熟悉,但从结构/逻辑流程的角度来看,这可能会有所帮助:
我认为您的问题可能是您在处理之前将整个文件解析到内存中:要实现这一点,您需要一次只处理一个单词。一些快速谷歌搜索引导我到this文章,这使得你似乎可以从你的文件中读取一行,计算它,插入你的形状,然后继续下一个单词,这将防止你吃大量的记忆。
答案 2 :(得分:0)
您可以使用nsynjs按顺序执行IO调用和逻辑的混合。以下是代码需要转换的步骤:
步骤1.将带有回调的慢速函数包装到nsynjs-aware包装器中:
dbWrappers.js:
// wrapper for remove
exports.remove = function (ctx, collection) {
collection.remove().exec(function(err){
ctx.resume(err);
});
};
exports.remove.nsynjsHasCallback = true;
// wrapper for save
exports.save = function (ctx, entry) {
entry.save(function(err){
ctx.resume(err);
});
};
exports.save.nsynjsHasCallback = true;
对于readFileAsync,您可以使用此包装器:https://github.com/amaksr/nsynjs/blob/master/wrappers/nodeFsReadFile.js
步骤2.将您的逻辑编写为同步,并将其置于函数中:
var populateDictionary = function(Word, dbWrappers, readFile) {
dbWrappers.remove(nsynjsCtx,dict); // use wrapper .remove from above,
// nsynjs will wait until callback in the wrapper complete
var data = readFile(nsynjsCtx, 'path').data; // use wrapper for fs.readFile
var dictionary = data.split('\n');
for (var i = 0; i < dictionary.length; i++) {
var entry = new Word({
word: dictionary[i],
lettersCount: {
'a': 0, 'b': 0, 'c': 0, 'd': 0,
'e': 0, 'f': 0, 'g': 0, 'h': 0,
'i': 0, 'j': 0, 'k': 0, 'l': 0,
'm': 0, 'n': 0, 'o': 0, 'p': 0,
'q': 0, 'r': 0, 's': 0, 't': 0,
'u': 0, 'v': 0, 'w': 0, 'x': 0,
'y': 0, 'z': 0
}
});
for (var j = 0; j < entry.word.length; j++) {
entry.lettersCount[entry.word[j]]++;
}
console.log(entry);
dbWrappers.save(nsynjsCtx,entry); // use wrapper '.save' from step 1
}
};
步骤3.通过naynjs:
以同步方式运行该功能var dbWrappers = require('dbWrappers');
var readFile = require('nodeFsReadFile').readFile;
var populateDictionary = function(Word, dbWrappers, readFile) {
....
}
nsynjs.run(populateDictionary,{},Word, dbWrappers, readFile, function(){
console.log('loading done');
})
参见类似示例https://github.com/amaksr/nsynjs/tree/master/examples/node-mysql(它将任何数字记录插入MySQL)。