【问题标题】:Search with Turkish characters使用土耳其语字符搜索
【发布时间】:2014-08-09 08:09:54
【问题描述】:

我在使用土耳其大写和小写的 like 和弹性搜索的 db 搜索时遇到问题。

例如,我有一个帖子表,其中包含标题为 '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。 如何在不输入确切单词的情况下获得正确的结果?

【问题讨论】:

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


    【解决方案1】:

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

    select * from posts where title <b>ilike</b> '%yazı%';

    但是,土耳其语言环境中的特殊规则还有额外的复杂性。 'ı' 的大写为 'I'。但不是反过来。 'I'的小写为'i'

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

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

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

    【讨论】:

    • 你成就了我的一天!
    【解决方案2】:

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

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

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

    • UPPER('İ') 返回 'İ' 正常
    • UPPER('i') 返回 'I' 不行
    • UPPER('I') 返回 'I' OK
    • UPPER('ı') 返回 'İ' 不行

    所以

    • SELECT ... FROM ... WHERE ... UPPER('İZMİR') like UPPER('izmir') return false
    • SELECT ... FROM ... WHERE ... UPPER('ISPARTA') like 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İ'))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-18
      • 2015-01-07
      • 2018-08-03
      • 1970-01-01
      • 2014-07-25
      • 2021-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多