PostgreSQL 不区分大小写和不区分重音的搜索
PostgreSQL case-insensitive and accent-insensitive search
我有一个数据 table,我想过滤列。例如,按全名搜索用户。
但是,我想允许用户输入不区分大小写和重音的搜索短语。
所以我检查了这些(以及更多)来源和问题:
我认为非确定性归类最终可能是实现该目标的正确方法,但不幸的是我不知道如何实现:
- 将 case_insensitive 和 ignore_accents 合并为一个排序规则
- 如何允许在此类 WHERE 中仅按子字符串搜索(例如,仅按字符串“joh”查找“Jóhn Doe”),因为非确定性归类不支持 LIKE 或正则表达式
- 使用哪个索引
对于如何最终处理此类问题的任何建议,我将不胜感激。
谢谢!
创建不区分大小写和重音的 ICU 排序规则非常简单:
CREATE COLLATION english_ci_ai (
PROVIDER = icu,
DETERMINISTIC = FALSE,
LOCALE = "en-US-u-ks-level1"
);
或者,等效地(该语法也适用于旧的 ICU 版本:
CREATE COLLATION english_ci_ai (
PROVIDER = icu,
DETERMINISTIC = FALSE,
LOCALE = "en-US@colStrength=primary"
);
有关详细讨论,请参阅 the ICU documentation for details and my article。
但是你的问题是你想要子字符串搜索。所以你应该创建一个三元组索引:
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS unaccent;
CREATE INDEX ON tab USING gin (unaccent(doc) gin_trgm_ops);
那么你可以这样搜索:
SELECT * FROM tab
WHERE unaccent(doc) ILIKE unaccent('%joh%');
请注意,如果您希望搜索字符串有效,则必须强制搜索字符串的最小长度为 4 左右。
我有一个数据 table,我想过滤列。例如,按全名搜索用户。
但是,我想允许用户输入不区分大小写和重音的搜索短语。
所以我检查了这些(以及更多)来源和问题:
我认为非确定性归类最终可能是实现该目标的正确方法,但不幸的是我不知道如何实现:
- 将 case_insensitive 和 ignore_accents 合并为一个排序规则
- 如何允许在此类 WHERE 中仅按子字符串搜索(例如,仅按字符串“joh”查找“Jóhn Doe”),因为非确定性归类不支持 LIKE 或正则表达式
- 使用哪个索引
对于如何最终处理此类问题的任何建议,我将不胜感激。
谢谢!
创建不区分大小写和重音的 ICU 排序规则非常简单:
CREATE COLLATION english_ci_ai (
PROVIDER = icu,
DETERMINISTIC = FALSE,
LOCALE = "en-US-u-ks-level1"
);
或者,等效地(该语法也适用于旧的 ICU 版本:
CREATE COLLATION english_ci_ai (
PROVIDER = icu,
DETERMINISTIC = FALSE,
LOCALE = "en-US@colStrength=primary"
);
有关详细讨论,请参阅 the ICU documentation for details and my article。
但是你的问题是你想要子字符串搜索。所以你应该创建一个三元组索引:
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS unaccent;
CREATE INDEX ON tab USING gin (unaccent(doc) gin_trgm_ops);
那么你可以这样搜索:
SELECT * FROM tab
WHERE unaccent(doc) ILIKE unaccent('%joh%');
请注意,如果您希望搜索字符串有效,则必须强制搜索字符串的最小长度为 4 左右。