搜索土耳其字符

时间:2014-06-18 21:48:58

标签: postgresql search elasticsearch pattern-matching sql-like

我在使用土耳其大写和小写的类似和弹性搜索进行数据库搜索时遇到问题。

例如,我有帖子表,其中包含标题为'DENEME YAZI'的帖子。

如果我运行此查询:

select * from posts where title like '%deneme%';

或:

select * from posts where title like '%YAZI%';

我得到了正确的结果,但如果我跑:

select * from posts where title like '%yazı%';

它不会返回任何记录。我的数据库编码是tr_TR.UTF-8。 如果不输入确切的单词,我怎样才能得到正确的结果?

2 个答案:

答案 0 :(得分:0)

您必须使用ILIKE进行不区分大小写的匹配:

select * from posts where title ilike '%yazı%';

然而,土耳其语语言环境中存在特殊规则的额外复杂性。 'ı' 的大写字母为 'I' 。但不是相反。 'I' 的小写字母为 'i'

db=# SELECT lower(upper('ı'));
 lower
-------
 i

可以通过在upper()表达式的任意一侧应用LIKE来解决这个问题:

select upper('DENEME YAZI') like ('%' || upper('yazı') || '%');

答案 1 :(得分:0)

在表达式的任一侧仅应用单个UPPER(或LOWER)不是解决方案。您应该自己处理有问题的土耳其语字符(ıI-iİ)。

  • İ和i在土耳其字母中是相同的字母。
  • 我和ı在土耳其字母中是相同的字母。

但即使在postgre中使用UTF-8,Latin5,Windows 1254编码和排序规则设置

  • UPPER('İ')返回'İ'OK
  • UPPER('i')返回'I'OK
  • UPPER('I')返回'I'OK
  • UPPER('ı')返回'İ'不好

如此

  • SELECT ... FROM ... WHERE ...像UPPER('izmir')一样的UPPER('İZMİR')返回false
  • SELECT ... FROM ... WHERE ... UPPER('ISPARTA')之类的UPPER('ısparta')返回false。

这是一些更精确,但由于性能问题而不完美的解决方案

SELECT ... FROM ... WHERE ... 
UPPER(REPLACE(REPLACE(COLUMNX, 'i', 'İ'), 'ı', 'I')) = UPPER(REPLACE(REPLACE(myvalue, 
'i', 'İ'), 'ı', 'I'))

SELECT ... FROM ... WHERE ... 
UPPER(TRANSLATE('COLUMNX','ıi','Iİ')) = UPPER(TRANSLATE(myvalue,'ıi','Iİ'))