使用Rails进行Postgres全文搜索的单词分隔符

时间:2012-12-30 18:11:42

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

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

Unfortuantelly Postgres似乎没有将/.识别为单词分隔符,因此我无法在url内搜索。

示例:在http://test.com中搜索test不会产生任何结果。

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

2 个答案:

答案 0 :(得分:5)

正如文档中所述(并且由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)

要对网址进行FT搜索,您只需要针对此字段进行查询。

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

答案 1 :(得分:1)

我最终修改了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"}}