我在模型中使用pg_search进行一些文本搜索。在其他属性中,我有一个url
字段。使用Rails进行Postgres全文搜索的词分隔符
不幸的是,Postgres似乎没有将/
和.
识别为单词分隔符,因此我无法在url
内进行搜索。
示例:在http://test.com中搜索test
不会产生任何结果。
有没有办法解决这个问题,也许使用另一个宝石或一些内联SQL?
我在模型中使用pg_search进行一些文本搜索。在其他属性中,我有一个url
字段。使用Rails进行Postgres全文搜索的词分隔符
不幸的是,Postgres似乎没有将/
和.
识别为单词分隔符,因此我无法在url
内进行搜索。
示例:在http://test.com中搜索test
不会产生任何结果。
有没有办法解决这个问题,也许使用另一个宝石或一些内联SQL?
正如文档中所述(并由AJcodez注意到),有一个解决方案为tsvector索引创建专用列。然后定义映入插入到索引网址正确的触发:
CREATE test_url (url varchar NOT NULL, url_tsvector tsvector NOT NULL);
此方法将transorm任何非字母字符转换成单一的空间,并转动字符串转换成的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;
你不如果您使用[功能索引](http://www.postgresql.org/docs/8.4/static/indexes-expressional.html),甚至需要额外的列。此外,您可以创建一个[view](http://www.postgresql.org/docs/8.4/static/tutorial-views.html),以避免需要指定用于创建索引的表达式的完整形式执行查询。 –
正如你所建议的那样,我破解了这个gem来支持任意的ts_vector调用,这将允许我使用'regexp_replace'。 使用插入/更新触发器可能会带来性能上的好处,但我觉得这个解决方案对我的需求来说太麻烦了。 感谢您的帮助。 – mihai
作为变通,你可以有另一列/使用url属性和公认的字分隔符,并搜索针对代替 – AJcodez