Reputation: 1050
I have configured full text search on some tables in postgres DB. When I try to build tsquery with more than 1 word I get words in tsquery with & (AND) as delimiter. In effect I can't find results where is only one of words what I asked.
Example:
| ID | Name | Description | Rank |
|----|---------|---------------------|------|
| 1 |Somethink|This is very strange | 0.2 |
| 2 |Other |This is strange a bit| 0 |
When I ask for "very strange" my tsquery looks like that 'very' & 'strange'
, and ranks (ts_rank_cd) for that tsquery is more than 0 only for ID == 1, for ID == 2 is 0.
My goal is to achieve rank > 0 for 2nd sentence. How to achieve this?
Upvotes: 1
Views: 1695
Reputation: 3536
You can create an OR
version of plainto_tsquery
by doing something along the lines of:
select replace(plainto_tsquery('foo bar')::text, '&', '|')::tsquery;
Similar to what klin advised but takes advantage of the stemming capabilities of plainto_tsquery
.
As an aside, I believe very
is a stop word so it won't be included in any to_tsquery
or plainto_tsquery
output.
Upvotes: 5
Reputation: 121764
Use OR
instead of AND
in the tsquery:
with data(d) as (
values
('This is very strange'),
('This is strange a bit')
)
select d, ts_rank_cd(to_tsvector(d), 'strange | very'::tsquery)
from data
d | ts_rank_cd
-----------------------+------------
This is very strange | 0.2
This is strange a bit | 0.1
(2 rows)
You can automatically change a user input using the function replace()
, e.g.:
with data(d) as (
values
('This is very strange'),
('This is strange a bit')
),
query (query) as (
values
('very & strange')
)
select d, ts_rank_cd(to_tsvector(d), replace(query, '&', '|')::tsquery)
from data
cross join query;
Upvotes: 1