下面有一组表,供其他表参考以用于位置数据。一些示例是:
我们也通过与州匹配来解决名称相似的多个城市的问题,但是现在遇到了一系列不同的问题。我们将Google的地方自动填充功能用于地理编码,并与我们的城市匹配用户查询。在Google的格式偏离我们的格式之前,此方法相当有效。
示例:
St. Louis !== Saint Louis
和
Ameca 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提供了我不知道的城市名称导出)。
答案 0 :(得分:1)
简短的答案是,您可以使用Postgres的全文搜索功能以及自定义的搜索配置。
由于处理地名,您可能希望避免词干,因此可以将简单配置用作起点。您还可以添加对地名有意义的停用词(在上面的示例中,您可以将“ St。”,“ Saint”和“ del”视为停用词)。
设置自定义内容的基本概述如下:
$SHAREDIR/tsearch_data
Postgres目录中。参见https://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html#TEXTSEARCH-STOPWORDS。pg_catalog.simple
用作模板字典)。参见https://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html#TEXTSEARCH-SIMPLE-DICTIONARY。另一个考虑因素是如何考虑国际化。您的第二个示例(Ameca del Torro
与Ameca 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')