使用Node.js在Mongodb中嵌套插入

时间:2015-06-08 03:00:11

标签: node.js mongodb

我收到的CSV文件包含产品列表。每个产品都有一个类别。当我保存产品时,我必须找到数据库中是否已存在该类别,如果不存在,我必须在保存产品之前创建它(并保存)。

module.exports.do_import = function (req, res) {
var final_json = {};
fs.createReadStream(req.files.file.path)
    .pipe(csv({
        separator: ';'
    }))
    .on('data', function (data) {

        mongoose.model("Category").findOne({nombre: data.NOMBRE}, function (err, category) {
            if (category == null) {
                var created_category = new Category({nombre: data.NOMBRE});
                created_category.save(function (err, __category) {
                                            var product = new Product({
                        nombre: data.NOMVDA,
                        categoria: __category,
                        codigo: data.CODVAR
                    });
                    product.save(function (err, prod) {
                        if (err) {
                            final_json.success = false;
                            res.json(final_json);
                        }
                    });
                });
            } else {
                var product = new Product({
                    nombre: data.NOMVDA,
                    categoria: category,
                    codigo: data.CODVAR
                });
                product.save(function (err, prod) {
                    if (err) {
                        final_json.success = false;
                        res.json(final_json);
                    }
                });
            }
        });
    }).on('finish', function () {
        final_json.success = true;
    }).on('error', function () {
        final_json.success = false;
    }).on('end', function () {
        res.json(final_json);
    });

所以,我遇到的麻烦是类别的.save()函数是异步执行的,所以当请求文件的下一条记录时,前一条记录的类别不是。保存了,所以它创建了两次相同的类别。如何让函数等到保存操作完成?

1 个答案:

答案 0 :(得分:0)

最后,我的一位朋友帮助了我,感谢https://nodejs.org/api/stream.html#stream_readable_pause我们可以让流程停止,直到产品已经创建完毕。 这是最终的代码:

module.exports.do_import = function (req, res) {
var final_json = {};

var readable = fs.createReadStream(req.files.file.path)
    .pipe(csv({separator: ';'}));

function saveErrorHandler(err, prod) {
    if (err) {
        final_json.success = false;
        res.json(final_json);
    }
    readable.resume();
    console.log('next category');
}

readable.on('data', function (data) {
    console.log('data');
    readable.pause();
    console.log('pausa');
    mongoose.xmodel("Category").findOne({nombre: data.NOMBRE}, function (err, category) {
        // Manejá el error que no lo tenes.
        if (category) {
            // esto se podría sacar ya que esta duplicado, pasale la categoría a una función
            var product = new Product({
                nombre: data.NOMVDA,
                categoria: category,
                codigo: data.CODVAR
            });
            product.save(saveErrorHandler);
        } else {
            var created_category = new Category({nombre: data.NOMBRE});
            created_category.save(function (err, __category) {
                var product = new Product({
                    nombre: data.NOMVDA,
                    categoria: __category,
                    codigo: data.CODVAR
                });
                product.save(saveErrorHandler);
            });
        }
    });
});

readable.on('finish', function () {
    final_json.success = true;
});

readable.on('error', function () {
    final_json.success = false;
});

readable.on('end', function () {
    res.json(final_json);
});