【问题标题】:Search for an exact part of sentence in PostgreSQL在 PostgreSQL 中搜索句子的确切部分
【发布时间】:2020-04-02 16:51:12
【问题描述】:

我有一个 PostgreSQL 数据库表,其中的行包含一些句子/文本段落。

假设有三个记录(无意义,仅举例):

1) A dancing fox ran across the road.
2) I like dancing foxtrot.
3) These animals are foxes.

我想搜索“dancing fox”,我希望它只返回“record 1”。

但是,当我使用通配符 %dancing fox% LIKE 语法时,我将检索记录 1 和 2。

我预计 ts_vector 可能是一个解决方案,但该项目使用更多语言环境(问题 1),我不希望它与第三条记录匹配 - 我不想要真正的全文(问题 2)。

请问您建议使用什么?或者您有任何经验或资源链接如何处理问题 1 和 2?

我知道我的问题很令人困惑,所以感谢您的耐心等待。也许我只需要被推向正确的方向。

【问题讨论】:

  • 您能否在通配符搜索中添加前导/滞后空间?
  • “我预计 ts_vector 可能是一个解决方案,但该项目使用了更多的语言环境(问题 1)”您能否更详细地解释一下,也许可以通过示例,这会是一个问题吗?跨度>
  • @jjanes 我预计“简单”字典/搜索配置还包含特定于区域设置的停用词等,但它似乎不是真的。

标签: sql regex postgresql full-text-search where-clause


【解决方案1】:

您可以使用正则表达式来做到这一点。

单词边界\y 派上用场:除了分隔单词的空格之外,可能还有其他字符。

where mycol ~ '\ydancing fox\y'

As explained in the documentation\y 仅匹配单词的开头或结尾

【讨论】:

    【解决方案2】:

    您可以添加分隔符:

    where concat(' ', col, ' ') like '% dancing fox %'
    

    【讨论】:

    • 为什么是 concat?这是为了说明整个值只是 dancing fox 的可能性吗?
    • 这在句尾标点前找不到。
    【解决方案3】:

    您可以使用带有“简单”配置的全文搜索来避免特定语言的词干和停用词,并使用短语匹配运算符来维护词序和间距。

    select * from foo 
        where to_tsvector('simple',x)  @@ phraseto_tsquery('simple','dancing fox');
    

    您说您不想匹配第 3 个示例,但不清楚为什么它首先会这样做,即使您使用的是 'english' 和 plainto_tsquery 而不是 'simple' 和 @987654323 @。

    您仍然受制于默认的 FTS 文本解析器认为是一个词,但您的示例都没有涉及这一点(如果 fox-trot 被连字符怎么办?)

    这将由 tsvector 类型上的常用 FTS 索引支持。

    或者按照 GMB 的建议,您可以使用 ~ 和 '\y'。 pg_trgm 索引将支持这种类型的查询。我认为这个解决方案更直观,但如果涉及的文本很长,效率可能会降低。

    【讨论】:

    • 我必须处理带连字符的复合词,我想找到“dancing-fox”,而不是“dancing fox-trot”,所以我会使用短语to_tsquery。我也可能会创建一个来自 simple 的特殊文本搜索配置(因为没有重音,我之前没有提到它,因为我希望存储两种文本变体 - 有和没有重音)。您的回答似乎很符合我的要求,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 2021-09-17
    • 2012-07-20
    相关资源
    最近更新 更多