【问题标题】:Postgres...how to improve ilike results (quality not speed)Postgres ...如何提高 ilike 结果(质量而不是速度)
【发布时间】:2020-10-02 14:09:10
【问题描述】:

我的数据库中有一份化学品清单,我为我们的用户提供了通过我们的网站进行实时搜索的能力。我使用 SQLAlchemy,我使用的查询看起来像这样:

Compound.query.filter(Compound.name.ilike(f'%{name}%')).limit(50).all() 

例如,当有人搜索 甲苯 时,他们并没有得到他们正在寻找的结果,因为有许多化学品中含有甲苯这个词,例如:

  • 2、4二硝基甲苯
  • 2-氯乙基对甲苯磺酸盐
  • 4-溴甲苯
  • 6-氨基间甲苯磺酸
  • a,2,4-三氯甲苯
  • a,o-二氯甲苯
  • a-溴甲苯
  • 等等……

我意识到我可以增加我的limit,但我觉得 50 已经绰绰有余了。或者,我可以将ilike(f'%{name}%')) 更改为ilike(f'{name}%')),但我们的业务需求不希望这样。我宁愿做的是提高 Postgres 返回结果的能力,使 甲苯 位于搜索结果的顶部。

对 Postgres 的 ilike 功能有何想法?

提前致谢。

【问题讨论】:

    标签: postgresql sqlalchemy


    【解决方案1】:

    一种选择是更好地对结果进行排名。 Postgres text search allows you to rank the results.

    一种廉价而肮脏的优先排名版本是使用unionname = ?ilike(f'{name}%'))ilike(f'%{name}%')) 进行多次查询。这样ilike(f'{name}%')) 结果就排在第一位了。

    提供分页,而不是硬性限制。 SQLAlchemy 有 paginate 提供帮助。

    【讨论】:

      【解决方案2】:

      ILIKE 产生一个布尔值。它没有指定返回结果的顺序,只是是否返回它们(您可以按布尔值排序,但如果您只返回 true,则没有什么可排序的)。因此,当您完成改进时,它根本不再是 ILIKE,而是完全不同的东西。

      您可能正在从pg_trgm 中寻找类似<-> 的东西,它提供了一个可以排序的距离分数。虽然实际上,您可以根据复合名称的长度对结果进行排序,并返回包含目标的最短 50 个。

      类似 ilike(f'{name}%')) 但我们的业务需求不希望这样

      您的业务要求不是获得更好的结果吗?

      但至少在我的数据库中,这可能只会返回一堆倒置格式的名称,例如toluene, 2,4-dinitro,因此结果可能不会好多少,除非您避免存储此类倒置名称。按 或按长度排序可以解决这个问题。但是如果你有这样的名字,他们也会惩罚toluene, ACS reagent grade 99.99% by HPLC

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-14
        • 1970-01-01
        • 1970-01-01
        • 2023-01-25
        • 2022-01-22
        • 2016-03-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多