首页 > 解决方案 > 如何使用 PostgreSQL 全文搜索返回部分短语匹配而不返回太多行?

问题描述

我正在使用pg_searchgem 在 PostgreSQL 中执行全文搜索,并且运行良好。但是,某些搜索在应有的情况下没有返回任何视频结果。

例如,搜索“物质状态”会返回 10 个结果,因为视频有一个名为“物质状态”的标签。但是“3 种物质状态”返回零结果。同样,“放射性碳测年”返回 1 个视频,但“碳测年”不返回任何内容。

这是我设置模型的方式:

# app/models/video.rb
class Video < ApplicationRecord
  include PgSearch::Model

  ...

  pg_search_scope(:user_search, {
    against: {
      title: 'C',
      description: 'D'
    },
    associated_against: {
      tags: { name: 'A' }
    },
    using: {
      tsearch: {
        prefix: true,
        dictionary: "english"
      }
    }
  })

  ...

end

要运行搜索:

query = "3 states of matter"
results = Video.user_search(query)

如果我使用其他选项,例如 trigram 或any_word,它会返回太多不相关的结果。

如何通过部分匹配改进全文搜索功能并避免返回太多不相关的结果?我更喜欢使用 的解决方案pg_search,但是如果我需要远离 gem,那么我会的。

标签: ruby-on-railspostgresqlfull-text-searchpg-search

解决方案


希望您尝试trigram使用默认阈值(即0.3)的选项。您可以尝试增加阈值以查找严格匹配。查看 gem 文档以获取更多信息 - Trigram#threshold

默认情况下,trigram 搜索使用 pg_trgm 的计算查找相似度至少为 0.3 的记录。如果您愿意,可以指定自定义阈值。数字越大匹配越严格,因此返回的结果越少。较低的数字更容易匹配,从而获得更多结果。请注意,设置三元组阈值将强制执行表扫描,因为派生查询使用相似度()函数而不是 % 运算符。

查看以下内容并根据您的桌子大小决定,

请注意,设置三元组阈值将强制执行表扫描,因为派生查询使用相似度()函数而不是 % 运算符。

了解如何计算三元词相似度。请检查此https://www.postgresql.org/docs/9.6/pgtrgm.html,您可以根据需要的比较级别设置阈值。


推荐阅读