То, что я пытаюсь сделать, читается в.txt файле слов, разрезает их на новые строки, а затем для каждого слова в построенном массиве выполняет операции над словом (которое соответствует используемой схеме Word) определите количество букв для каждого слова, например, для слова (0 A, 0 B, 1 W, 1 O, 1 R, 1 D, OZ и т.д.), а затем вставьте каждое 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
, я 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();
}
});
};
Итак, я довольно новичок в базах данных, но думаю, что там есть хорошее решение, просто не знаю, что... Я в основном создаю огромный стек вызовов, и он разбивает мой компьютер. Я ищу правильный способ сделать это. Благодарю!
Я бы предложил асинхронную библиотеку. Он имеет много полезных методов. Я использовал async.eachLimit, ниже которого ограничивает операции async предоставленному числу.
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]]++;
}
}
Вы можете последовательно исполнять смесь вызовов IO и логики с помощью nsynjs. Вот шаги, которые необходимо преобразовать код:
Шаг 1. Оберните медленные функции с помощью обратных вызовов в обертки, совместимые с nsynjs:
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).
Я не очень хорошо знаком с точными технологиями, которые вы используете, но с точки зрения структуры/логики, может быть, это поможет:
Я думаю, что ваша проблема может заключаться в том, что вы разбираете весь файл в памяти перед обработкой: это много, чтобы удержать, когда на самом деле вы просто хотите обрабатывать одно слово за раз. Некоторые быстрые Googling приводят меня к этой статье, из-за которой вам кажется, что вы можете прочитать строку из вашего файла, считать ее, вставить свою фигуру и перейти к следующему слову, которое должно помешать вам съесть тонну памяти.