postgres同义词和前缀结果在一起

时间:2014-06-27 20:17:50

标签: postgresql full-text-search

我有同义词:lake lac loch 当我在postgres为'湖'做fts时,我希望得到所有包含' lake'' lac'和' loch' (我使用同义词作为.syn文件或.rules文件)。但是,我也希望得到以' lake'开头的字样,如湖景'。如果我使用同义词,我就不会获得前缀匹配,当我不使用同义词时,我会得到前缀匹配...我怎样才能得到两者?有没有办法关闭同义词所以我提出一个问题来获取同义词而忽略它们?我尝试过'喜欢'和'位置'但它太慢了。

.rules有: Lake lac湖 湖湖紫胶 Lac湖湖

.syn有: 湖yyyyy lac yyyyy 可是yyyyy

我试过了两个,但同样的问题。如果我在.syn文件中将所有同义词映射到其中一个: 湖湖 紫胶湖 湖湖

......我会得到' lakefield'但不是' lacombe' (我需要它们全部使用前缀)。

我正在使用PostgreSQL 9.3。

查询是:

select 
    *, 
    ts_rank_cd(to_tsvector('location', name), to_tsquery('location', 'lac:*'),16) as ftsrank
from profile_name 
where iso_code='en-CA' 
  AND to_tsvector('location', name) @@ to_tsquery('location', 'lac:*') 
  AND ts_rank_cd(to_tsvector('location', name), to_tsquery('location', 'lac:*'),16) >= 0
order by ftsrank desc 

profile表格包含我要搜索的name字段。

谢谢, Zorica

2 个答案:

答案 0 :(得分:0)

你能否使用查询重写功能?

select
ts_rewrite('lake'::tsquery, 'lake'::tsquery, 'lake:* | lac | loch'::tsquery) @@ 'lake'::tsvector, --true
ts_rewrite('lake'::tsquery, 'lake'::tsquery, 'lake:* | lac | loch'::tsquery) @@ 'loch'::tsvector, --true
ts_rewrite('lake'::tsquery, 'lake'::tsquery, 'lake:* | lac | loch'::tsquery) @@ 'lakefield'::tsvector --true

您也可以在数据库表中重写您的查询。

答案 1 :(得分:0)

这就是我解决问题的方法: 我添加了一个新的fts(全文搜索)配置,该配置不使用同义词并在to_tsquery中引用要键入的关键字用户进行搜索。对于上面的示例,它看起来像这样:

select 
    *, 
    ts_rank_cd(to_tsvector('location', name), to_tsquery('location_nosyn', 'lac:*'),16) as ftsrank
from profile_name 
where iso_code='en-CA' 
  AND to_tsvector('location', name) @@ to_tsquery('location_nosyn', 'lac:*') 
  AND ts_rank_cd(to_tsvector('location', name), to_tsquery('location_nosyn', 'lac:*'),16) >= 0
order by ftsrank desc 

...其中提到'location_nosyn'fts不识别同义词的配置。请注意,我仍然使用数据库字段'name'的同义词,因此它将从db中获取所有同义词。但是,不使用关键字的同义词会使部分匹配工作(如果用户输入'lac',它们将获得像'Lake'这样的同义词,但它们也会得到'Lacey'而不是'Lakewood'......这正是我需要的)。

希望这会帮助其他有类似问题的人。 感谢所有回复的人!