我正在用巴西葡萄牙语开发一个简单的文章网站。搜索功能基于全文搜索,但未返回预期结果。
我在postgresql上做了这个。这是简化表:
Artigos
-id
-title -- article title
-intro -- article introduction
-content -- article body
-publishdate -- date of launch
-artigosts -- this will work as our fts index.
创建表后,我跑了:
UPDATE artigos SET artigosts =
setweight(to_tsvector('pg_catalog.portuguese', coalesce(title,'')), 'A') ||
setweight(to_tsvector('pg_catalog.portuguese', coalesce(intro,'')), 'B') ||
setweight(to_tsvector('pg_catalog.portuguese', coalesce(content,'')), 'C');
CREATE INDEX artigosts_idx ON artigos USING gist (artigosts);
CREATE TRIGGER artigosts_tg
BEFORE INSERT OR UPDATE ON artigos
FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger('artigosts', 'pg_catalog.portuguese', 'title', 'intro', 'content');
是的,我打算在搜索中使用简单的加权。制作了一个加速索引,一个触发器,所以我可以插入和更新而不用担心重建索引等等。
嗯,根据我的理解,一切都很好。但结果不是。一个简单的例子。
假设我有“... banco de dados ...没有银行......”作为一篇文章的内容。当我这样做时:
SELECT title, intro, content FROM artigos WHERE plainto_tsquery('banco de dados') @@ artigosts;
返回一个空集。我查看了ts_vector列,看到了谓词'banc'和'dad'。但我仍然无法理解为什么它不会返回包含上述文章的行。
有人可以为这个问题带来启示吗?
答案 0 :(得分:5)
原因可能是因为您的默认字典设置为英语。请尝试以下查询以确定是否确实如此。
SELECT * FROM ts_debug('banco de dados');
此查询将显示字典如何解析您的搜索短语。它应该提供lexemes“banco”,“de”和“dado”。因此,您实际搜索的内容将不会存在于索引中,您将收到0个结果。
现在试试这个:
SELECT * FROM ts_debug('portuguese', 'banco de dados');
它应该返回索引中存在的词法“banc”和“dad”。如果是这种情况,那么您只需更改搜索查询即可获得相应的结果。
SELECT title, intro, content FROM artigos WHERE plainto_tsquery('portuguese', 'banco de dados') @@ artigosts;
答案 1 :(得分:1)
你可能要迟到了。 我没有足够的声誉来添加简单的评论...
关于特殊字符,我在转换为tsvector之前将它们取消了它们。
SELECT to_tsvector('simple',unaccent('banco de dados áéóíúçãõ'))
所以我得到了:
"'aeoiucao':4 'banco':1 'dados':3 'de':2"
你需要:
CREATE EXTENSION unaccent;
...作为用户postgres。 当然,你也必须解除你的tsquery