【问题标题】:Word separators for Postgres full text search with Rails使用 Rails 进行 Postgres 全文搜索的单词分隔符
【发布时间】:2012-12-15 02:51:21
【问题描述】:

我正在使用pg_search 在我的模型中进行一些文本搜索。在其他属性中,我有一个 url 字段。

不幸的是,Postgres 似乎没有将 /. 识别为单词分隔符,因此我无法在 url 中进行搜索。

示例:在 http://test.com 中搜索 test 没有结果。

有没有办法解决这个问题,也许使用另一个 gem 或一些内联 SQL?

【问题讨论】:

  • 作为一种变通方法,您可以使用另一个带有 url 和可识别单词分隔符的列/属性,然后对其进行搜索

标签: ruby-on-rails postgresql pg-search


【解决方案1】:

如文档中所述(并由 AJcodez 注意到),有一种解决方案可以为 tsvector 索引创建专用列。然后定义一个触发器来正确捕获对索引 url 的插入:

CREATE test_url (url varchar NOT NULL, url_tsvector tsvector NOT NULL);

此方法会将任何非字母字符转换为单个空格并将字符串转换为 tsvector:

CREATE OR REPLACE FUNCTION generate_url_tsvector(varchar) 
RETURNS tsvector 
LANGUAGE sql 
AS $_$
    SELECT to_tsvector(regexp_replace($1, '[^\w]+', ' ', 'gi'));
$_$;

现在创建一个调用此函数的触发器:

CREATE OR REPLACE FUNCTION before_insert_test_url()
RETURNS TRIGGER
LANGUAGE plpgsql AS $_$
BEGIN;
  NEW.url_tsvector := generate_url_tsvector(NEW.url); 

  RETURN NEW;
END;
$_$
;

CREATE TRIGGER before_insert_test_url_trig 
BEFORE INSERT ON test_url 
FOR EACH ROW EXECUTE PROCEDURE before_insert_test_url();

现在,当 url 被插入时,`url_tsvectorè 字段将被自动填充。

INSERT INTO test_url (url) VALUES ('http://www.google.fr');
TABLE test_url;

 id          url                     url_tsvector            

  2  http://www.google.fr  'fr':4 'googl':3 'http':1 'www':2 

(1 row)

要对 URL 进行 FT 搜索,您只需针对该字段进行查询。

SELECT * FROM test_url WHERE url_tsvector @@ 'google'::tsquery;

【讨论】:

  • 如果您使用functional index,您甚至不需要额外的列。此外,您可以创建view,以避免在执行查询时指定用于创建索引的表达式的完整形式。
  • 我破解了该 gem 以支持任意 ts_vector 调用,这将允许我按照您的建议使用 regexp_replace。使用插入/更新触发器可能会带来性能优势,但我发现这个解决方案对于我的需求来说有点太麻烦了。感谢您的帮助。
【解决方案2】:

我最终修改了 pg_search gem 以支持任意 ts_vector 表达式,而不仅仅是列名。 更改为here

现在我可以写了:

pg_search_scope :search, 
    against: [[:title , 'B'], ["to_tsvector(regexp_replace(url, '[^\\w]+', ' ', 'gi'))", 'A']],
    using: {tsearch: {dictionary: "simple"}}

【讨论】:

    【解决方案3】:

    稍微简单一点的方法,将协议令牌类型添加到simple 字典中:

    ALTER TEXT SEARCH CONFIGURATION simple
        ADD MAPPING FOR protocol
            WITH simple;
    

    如果需要词干,也可以将其添加到 english 字典中

    https://www.postgresql.org/docs/13/textsearch-parsers.html

    https://www.postgresql.org/docs/13/sql-altertsconfig.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-31
      • 1970-01-01
      • 2020-07-15
      • 2010-11-11
      • 1970-01-01
      • 2011-01-16
      • 2015-02-11
      相关资源
      最近更新 更多