2015-04-04 43 views
2

你好,我目前正在尝试从XML文件中插入数据到MySql数据库中。我正在使用Sails.js和waterline进行查询。 我的桌子是用户和宠物,一个用户可以有多个宠物,一个宠物可以有多个用户(所有者),所以我的连接表是users_pets。如何优化循环以插入数据库?

-I将XML文件转换为javascript对象,并通过循环来插入数据。我的问题是我需要循环是异步的,因为我不希望重复记录在宠物表中。对于每个迭代,我检查宠物是否存在,如果它不创建它,否则我将其ID插入到插入的用户中。如果这不是异步的,则同时触发多个“findOrCreate”触发器并在数据库中创建宠物副本。

如何优化此代码?对于125用户xml和他们的宠物,大约需要85秒。

XML:

<users> 
    <user> 
    <pets> 
     <pet> 
     </pet> 
    </pets> 
    </user> 
    ... 
</users> 

代码:

async.eachSeries(users, function(user, callback) { 
    var pets = []; 
    async.eachSeries(user.pets, function(pet, callback) { 
    pets.findOrCreate({name: pet.name}).exec(function (err,userPet) { 
     pets.push(userPet.id); 
     callback(); 
    }); 
    }, function(err){ 
    users.create({name: user.name, pets: pets}) 
    .exec(function(err, created) { 
     callback(); 
    }); 
    }); 
}, function(err){ 
    ... 
}); 
+0

http://codereview.stackexchange.com会更适合这 – laggingreflex 2015-04-04 14:51:22

+1

所以你的XML有重复的宠物?也许你可以先删除重复的条目,然后使用async.parallel而不是你的第一个async.eachSeries。 – Tulio 2015-04-04 14:54:54

+2

'如何优化循环以插入到数据库'通过不使用循环来插入到数据库中进行优化。你应该可以做一个批量插入。 – Brandon 2015-04-04 14:55:21

回答

1

在sails.js,您可以发送对象的数组.create()和一组ID为.find()。所以你可以做这样的事情:

Pet 
    .find(user.pets) 
    .then(function (pets) { 
     return User.create({ name: user.name, pets: pets }); 
    }) 
    .then(function (users) { 
     // done 
    }); 
+0

好吧,这是部分的,也许我不够清楚。在数据库中可能有一只宠物已经存在,我们只需要将它与现有的宠物关联起来,而不是创建一个新的宠物。当我导入xml数据时,可以添加一个宠物,并且可以在同一个xml中与另一个用户关联。 – user2663041 2015-04-04 22:09:04