【问题标题】:In Django with Postgresql 9.6 how to sort case and accent insensitive?在带有 Postgresql 9.6 的 Django 中,如何对大小写和重音不敏感?
【发布时间】:2017-10-14 16:11:46
【问题描述】:

我想要的是相当于在 MySQL 中使用utf8_unicode_ci。因此,如果我有这些字符串(使用 Postgresql 的默认排序顺序):

  • 谷仓
  • 气泡
  • 博夫
  • 牛肉
  • 肉丸
  • bémol

我希望它们能像这样排序(就像 MySQL 中的 utf8_unicode_ci 一样):

  • 谷仓
  • 牛肉
  • bémol
  • 博夫
  • 肉丸
  • 气泡

这种排序不区分大小写,不区分重音,并且连字会转换为多个字符。

我知道 Postgresql 中的 unaccentlower,但我不知道如何在 Django 中使用它们。

使用 Django/Postgresql 的可能解决方案:

  • 添加新列仅用于对数据进行规范化(较低、不重音)进行排序。
  • 添加索引 (like in this answer),但我不确定它如何与 Django 一起使用?

我不认为全文搜索或 Trigram 在这里可以帮助我,因为我不一定要根据文本进行搜索,但我需要获得良好的排序顺序。

理想情况下,查询应该很快,因此使用另一个索引列看起来是一个不错的途径。但我希望找到一个解决方案,我不需要为我的数据库中的每个现有文本列实施,易于维护等。是否有最佳实践来做到这一点?

【问题讨论】:

    标签: django postgresql sorting


    【解决方案1】:

    这与 Django 本身无关,PostgreSQL 的 lc_collate 配置决定了这一点。我建议你检查一下它的价值:

    SHOW lc_collate;
    

    正确的做法是修复此配置。也不要忘记查看相关设置(lc_ctype 等)。

    但如果您无法使用正确的设置创建另一个数据库,请尝试在 ORDER 上显式显示 collate,如以下测试用例:

    CREATE TEMPORARY TABLE table1 (column1 TEXT); 
    
    INSERT INTO table1 VALUES('Barn'),
    ('beef'),
    ('bémol'),
    ('Bœuf'),
    ('boulette'),
    ('Bubble');
    
    SELECT * FROM table1 ORDER BY column1 COLLATE "en_US"; --Gives the expected order
    SELECT * FROM table1 ORDER BY column1 COLLATE "C"; --Gives "wrong" order  (in your case)
    

    请务必记住 PostgreSQL 依赖于操作系统区域设置。此测试用例在 CentOS 7 上执行。更多信息 herehere

    【讨论】:

    • 据我所知,Postgresql 没有任何排序规则可以进行我想要的排序。如果你能证明我错了,我会很高兴的!
    • @Etienne 我在答案中添加了一个测试用例。
    • 我试过你的测试用例,SELECT 给出了相同的排序顺序。但是我在一个旧的 OS X 系统上阅读你的消息它记得我几年前我​​可能在这个系统上遇到过这个问题!我将在另一个系统上测试它并回来。谢谢!
    • 你说得对,我的问题是旧 OS X 系统上的系统语言环境不正确。是时候升级这个系统了!再次感谢。
    • 很高兴帮助你@Etienne
    【解决方案2】:

    我是这样做的:

    但你需要在你的 postgresql 中启用模块'unaccent',然后才能这样: CREATE EXTENSION unaccent;

    def get_value_ci(field):
        return Func(field, function='LOWER', template='UNACCENT(%(function)s(%(expressions)s))')
    
    YoutModel.objects.order_by(get_value_ci('nome_your_field'))
    

    并且有效,;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-09
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      相关资源
      最近更新 更多