Node.js中处理大型JSON文件实现天气应用自动补全接口
实现基于OpenWeatherMap城市列表的自动补全接口解决方案
一、处理OpenWeatherMap城市数据文件
OpenWeatherMap提供的城市列表是gzip压缩格式,需要先处理成精简的JSON文件:
- 下载压缩包并解压,得到
current.city.list.json - 编写脚本精简数据(只保留需要的
id、name、country字段,减少文件体积):
执行这个脚本后,把生成的const fs = require('fs'); // 读取原始城市文件 const rawCities = require('./current.city.list.json'); // 过滤并保留目标字段 const filteredCities = rawCities.map(city => ({ id: city.id, name: city.name, country: city.country })); // 写入精简后的文件到static目录 fs.writeFileSync('./static/filtered-cities.json', JSON.stringify(filteredCities));filtered-cities.json放到项目的static目录下。
二、修改服务端接口代码
由于原始城市数据量较大,直接import会导致内存占用过高,建议在服务端读取并缓存数据,同时调整过滤逻辑以返回指定格式:
import fs from 'fs/promises'; import path from 'path'; // 全局缓存城市数据,避免重复读取文件 let cachedCities = null; export default defineEventHandler(async (event) => { const { searchTerm } = getQuery(event); // 处理空搜索词或非字符串类型的情况 if (!searchTerm || typeof searchTerm !== 'string') { return { matches: [] }; } // 懒加载并缓存城市数据 if (!cachedCities) { try { const filePath = path.resolve(process.cwd(), 'static/filtered-cities.json'); const fileContent = await fs.readFile(filePath, 'utf-8'); cachedCities = JSON.parse(fileContent); } catch (error) { console.error('加载城市数据失败:', error); return { matches: [] }; } } const lowerSearch = searchTerm.toLowerCase(); // 过滤匹配的城市,保留指定字段 const matchingCities = cachedCities.filter(city => { const lowerCityName = city.name.toLowerCase(); const lowerCountry = city.country.toLowerCase(); return lowerCityName.startsWith(lowerSearch) || lowerCountry.startsWith(lowerSearch); }); return { matches: matchingCities }; });
三、性能优化建议
如果城市数据量极大(百万级以上),可以进一步优化查询效率:
- 预存小写字段:在精简数据的脚本中提前生成小写的
nameLower和countryLower字段,避免每次过滤时重复转小写:
对应过滤逻辑改为:const filteredCities = rawCities.map(city => ({ id: city.id, name: city.name, country: city.country, nameLower: city.name.toLowerCase(), countryLower: city.country.toLowerCase() }));return city.nameLower.startsWith(lowerSearch) || city.countryLower.startsWith(lowerSearch); - 使用数据库存储:将城市数据导入SQLite或其他轻量数据库,利用SQL的
LIKE查询或全文索引功能,进一步提升查询速度。
内容的提问来源于stack exchange,提问作者feusanc
相关产品推荐
相关产品推荐

