You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中处理大型JSON文件实现天气应用自动补全接口

实现基于OpenWeatherMap城市列表的自动补全接口解决方案

一、处理OpenWeatherMap城市数据文件

OpenWeatherMap提供的城市列表是gzip压缩格式,需要先处理成精简的JSON文件:

  1. 下载压缩包并解压,得到current.city.list.json
  2. 编写脚本精简数据(只保留需要的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 14:22:33