比较Node.js中两个大数组的值



我有两个数组,一个包含来自CSV文件的200.000个产品对象,另一个包含数据库的200000个产品对象。

两个数组都包含具有相同字段的对象,但有一个例外:数据库对象也具有唯一的ID。

我需要将所有200000个CSV对象与200000个数据库对象进行比较。如果CSV对象已经存在于数据库对象数组中,我将其与匹配的ID一起放入"更新"数组中,如果不存在,则将其放入"新"数组中。

完成后,我更新数据库中的所有"更新"对象,并插入所有"新"对象。这很快(几秒钟(。

然而,比较步骤需要数小时。我需要比较三个值:通道(字符串(、日期(日期(和时间(字符串(。如果三者都一样,那就是一场比赛。如果其中一个不是,那么这就不是一场比赛。

这是我的代码:

const newProducts = []; 
const updateProducts = [];
csvProducts.forEach((csvProduct) => {
// check if there is a match
const match = dbProducts.find((dbProduct) => {
return dbProduct.channel === csvProduct.channel && moment(dbProduct.date).isSame(moment(csvProduct.date), 'day') && dbProduct.start_time === csvProduct.start_time;
});
if (match) {
// we found a match, add it to updateProducts array
updateProducts.push({
id: match.id,
...csvProduct
});
// remove the match from the dbProducts array to speed things up
_.pull(dbProducts, match);
} else {
// no match, it's a new product
newProducts.push(csvProduct);
}
});

我正在使用lodashmoment.js库。

瓶颈在于检查是否匹配,有什么想法可以加快速度吗?

这是Map集合类的作业。数组是一个麻烦,因为它们必须线性搜索。可以快速搜索贴图(和集(。您希望在RAM中进行匹配,而不是为传入文件中的每个对象都打数据库。

因此,首先读取数据库中的每个记录,并构造一个Map,其中键是像{start_time, date, channel}这样的对象,值是id。(我把时间放在第一位,因为我想这是具有最多不同值的属性。这是为了加快查找速度。(

类似于这个伪代码的东西。

const productsInDb = new Map()
for (const entry in database) {
const key = {  // make your keys EXACTLY the same when you load your Map ..
start_time: entry.start_time,
date: moment(entry.date), 
entry.channel}
productsInDb.add(key, entry.id)
}

这将需要一大堆RAM,但那又怎样呢?这就是RAM的作用。

然后按照你在示例中的方式进行匹配,但要使用Map。

const newProducts = []; 
const updateProducts = [];
csvProducts.forEach((csvProduct) => {
// check if there is a match
const key = {     // ...and when you look up entries in the Map.
start_time: entry.start_time,
date: moment(entry.date), 
entry.channel}
const id = productsInDb.get(key)
if (id) {
// we found a match, add it to updateProducts array
updateProducts.push({
id: match.id,
...csvProduct
});
// don't bother to update your Map here 
// unless you need to do something about dups in your csv file
} else {
// no match, it's a new product
newProducts.push(csvProduct)
}
});

相关内容

  • 没有找到相关文章

最新更新