如何将用户输入与模糊的城市名称匹配?

时间:2019-06-27 18:01:35

标签: postgresql

下面有一组表,供其他表参考以用于位置数据。一些示例是:

  • 查找X市X英里范围内的所有公司
  • 将公司资料的位置创建为X City

Table Schema

我们也通过与州匹配来解决名称相似的多个城市的问题,但是现在遇到了一系列不同的问题。我们将Google的地方自动填充功能用于地理编码,并与我们的城市匹配用户查询。在Google的格式偏离我们的格式之前,此方法相当有效。

示例: St. Louis !== Saint LouisAmeca del Torro !== Ameca Torro

在我们的查询中是否可以模糊匹配城市?

我们匹配城市的查询现在看起来像:

SELECT c.id
FROM city c
INNER JOIN state s
ON s.id = c.state_id
WHERE c.name = 'Los Angeles' AND s.short_name = 'CA'

我还考虑了非正规化城市,只是存储坐标以仍然完成半径搜索。现在company表中大约有200万行,因此将在该半径表上执行半径搜索,而不是在city上使用JOIN的{​​{1}}表进行半径搜索。这也意味着我们将无法(无论如何)为城市创建自定义区域,并且将来无法向城市添加其他属性。

我发现了this answer,但它基本上肯定了我们标准化输入的方法是一种好方法,但不是我们如何与本地表匹配的方法(除非Google提供了我不知道的城市名称导出)。

1 个答案:

答案 0 :(得分:1)

简短的答案是,您可以使用Postgres的全文搜索功能以及自定义的搜索配置。

由于处理地名,您可能希望避免词干,因此可以将简单配置用作起点。您还可以添加对地名有意义的停用词(在上面的示例中,您可以将“ St。”,“ Saint”和“ del”视为停用词)。

设置自定义内容的基本概述如下:

  1. 创建一个停用词文件并将其放在您的$SHAREDIR/tsearch_data Postgres目录中。参见https://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html#TEXTSEARCH-STOPWORDS
  2. 创建一个使用此停用词列表的字典(您可以将pg_catalog.simple用作模板字典)。参见https://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html#TEXTSEARCH-SIMPLE-DICTIONARY
  3. 为地名创建搜索配置。参见https://www.postgresql.org/docs/9.1/static/textsearch-configuration.html
  4. 更改搜索配置以使用您在第2步中创建的字典(请参见上面的链接)。

另一个考虑因素是如何考虑国际化。您的第二个示例(Ameca del TorroAmeca Torro)的问题似乎可能是该名称的西班牙语还是英语表示形式。如果是这样,您还可以考虑存储城市名称的“本地化”和“通用”(例如英语)版本。

最后,您的查询(使用全文搜索)可能看起来像这样(其中“地方”是您的搜索配置的名称):

SELECT cities."id"
FROM cities
    INNER JOIN "state" ON "state".id = cities.state_id
WHERE
    "state".short_name = 'CA'
    AND TO_TSVECTOR('places', cities.name) @@ TO_TSQUERY('places', 'Los & Angeles')