MongoDB数组重复项处理:返回重复项与入库去重方案咨询
问题解答
1. 返回数组重复项并保存完整数组到MongoDB
步骤1:提取数组中的重复项
首先得明确“重复”的判断标准(比如大学名称name、域名domains或国家+名称组合),通过统计频次筛选重复条目:
// 以name作为重复判断键为例 const nameCount = new Map(); // 统计每个name的出现次数 returnApi.forEach(item => { const count = nameCount.get(item.name) || 0; nameCount.set(item.name, count + 1); }); // 筛选出重复的条目 const duplicateItems = returnApi.filter(item => nameCount.get(item.name) > 1);
步骤2:保存数据到MongoDB
- 原数组推荐用
bulkWrite替代循环create,减少数据库请求次数,提升效率 - 重复项可以单独存入一个集合(比如
UniversityDuplicates),方便后续排查
修改后的代码示例:
const hasDate = await Universities.find({ country }); if (hasDate.length > 0) { return new Error('Dados já existe'); } else { // 1. 提取重复项 const nameCount = new Map(); returnApi.forEach(item => { const count = nameCount.get(item.name) || 0; nameCount.set(item.name, count + 1); }); const duplicateItems = returnApi.filter(item => nameCount.get(item.name) > 1); // 2. 批量插入原数组数据 const bulkOps = returnApi.map(item => ({ insertOne: { document: { domains: item.domains, alpha_two_code: item.alpha_two_code, country: item.country, web_pages: item.web_pages, name: item.name, state_province: item.stateprovince } } })); await Universities.bulkWrite(bulkOps); // 3. 保存重复项到单独集合(如有) if (duplicateItems.length > 0) { await UniversityDuplicates.insertMany(duplicateItems); } await insertNameUniversities(returnApi); }
2. filter去重的系统影响与混合结构数组去重
filter去重的系统影响
- 小数据量:完全无影响,代码简洁易维护
- 大数据量(10w+条目):如果用
filter配合嵌套循环判断重复(比如filter((item, index) => returnApi.findIndex(...) === index)),时间复杂度为O(n²),会导致内存占用升高、处理变慢。这种情况建议用Map或Set优化,将时间复杂度降到O(n)
混合结构数组(对象+字符串)的去重方法
需要区分元素类型,针对性处理:
function deduplicateMixedArray(arr) { const seen = new Set(); return arr.filter(item => { let key; if (typeof item === 'string') { key = item; } else if (typeof item === 'object' && item !== null) { // 针对对象,用唯一标识(比如name+country)作为key,避免JSON.stringify的属性顺序问题 key = `${item.name}_${item.country}`; // 若无固定唯一键,也可使用JSON.stringify(需保证属性顺序一致) // key = JSON.stringify(item, Object.keys(item).sort()); } else { // 数字、布尔等类型直接转为字符串作为key key = String(item); } if (!seen.has(key)) { seen.add(key); return true; } return false; }); } // 使用示例 const deduplicatedApi = deduplicateMixedArray(returnApi);
结合你的代码优化
在插入前先执行去重,避免重复数据写入:
const hasDate = await Universities.find({ country }); if (hasDate.length > 0) { return new Error('Dados já existe'); } else { // 先对数组去重 const deduplicatedApi = deduplicateMixedArray(returnApi); // 批量插入去重后的数据 const bulkOps = deduplicatedApi.map(item => ({ insertOne: { document: { domains: item.domains, alpha_two_code: item.alpha_two_code, country: item.country, web_pages: item.web_pages, name: item.name, state_province: item.stateprovince } } })); await Universities.bulkWrite(bulkOps); await insertNameUniversities(deduplicatedApi); }
内容的提问来源于stack exchange,提问作者SD Penedo
相关产品推荐
相关产品推荐

