在Node.js中过滤大型JSON文件|天气应用的自动完成

2mbi3lxu  于 2023-03-31  发布在  Node.js
关注(0)|答案(1)|浏览(124)

我正在尝试在我的服务器上创建一个自动完成端点,我有一个很大的json文件,里面有我想自动完成的城市名称。但是我不知道如何解析/过滤它。
我想使用的json文件如下:https://bulk.openweathermap.org/sample/current.city.list.json.gz
上面json的示例数据:

[
  {
    "id": 14256,
    "coord": {
      "lon": 48.570728,
      "lat": 34.790878
    },
    "country": "IR",
    "geoname": {
      "cl": "P",
      "code": "PPL",
      "parent": 132142
    },
    "langs": [
      {
        "de": "Azad Shahr"
      },
      {
        "fa": "آزادشهر"
      }
    ],
    "name": "Azadshahr",
    "stat": {
      "level": 1.0,
      "population": 514102
    },
    "stations": [
      {
        "id": 7030,
        "dist": 9,
        "kf": 1
      }
    ],
    "zoom": 10
  },
  ...
]

我将如何以下面的格式返回匹配的城市:

{
  "matches": [
      {"id": 12312, "name": "New York", "country": "USA"}
  ]
}

下面是我当前代码:

import cities from "../../static/citynames.json"

export default defineEventHandler(async (event) => {
  const { searchTerm } = getQuery(event)
  if (!searchTerm) {
    return {
      matches: []
    }
  }

  const matching_cities = cities.filter(city => {
    const city_name = city.name.toLowerCase()
    const country_name = city.country.toLowerCase()

    return country_name.startsWith(searchTerm.toLowerCase()) || city_name.startsWith(searchTerm.toLowerCase())
  })

  return {
    matches: matching_cities
  }

})

这是我使用的json文件(从xlsx转换而来):https://openweathermap.org/storage/app/media/cities_list.xlsx
上面json的示例数据:

[
  {
    "name": "Abidjan",
    "lon": -4.00167,
    "lat": 5.35444,
    "country": "Ivory Coast"
  },
  {
    "name": "Abu Dhabi",
    "lon": 54.39696,
    "lat": 24.45118,
    "country": "United Arab Emirates"
  },
  ...
]

这一个没有id的,它的数据样本太小。

iqjalb3h

iqjalb3h1#

我对你的代码做了一些优化。
1.你应该试着把不必要的计算提取到迭代之外。像searchTerm.toLowerCase();一样,你不需要做一百万次。
1.您可以避免迭代中不必要的计算。如果国家已经匹配,则不需要检查city.name.toLowerCase().startsWith(searchTerm)
1.您可以考虑使用startsWith()的替代方法,这取决于数组和搜索项的内容,其中一种替代方法可能具有更高的性能。此链接上的一些基准测试。

import cities from "../../static/citynames.json";

export default defineEventHandler(async (event) => {
  const {searchTerm} = getQuery(event);

  if (!searchTerm) {
    return {
      matches: [],
    };
  }

  const search = searchTerm.toLowerCase();

  const matching_cities = cities.filter(city => city.country.toLowerCase().startsWith(search)
      || city.name.toLowerCase().startsWith(search));

  return {
    matches: matching_cities,
  };
});

相关问题