0

I have the following query that I did hard looking on this site:

SELECT *
FROM   renns
WHERE
    (
        to_tsvector('english', coalesce(numar_admin, '')) || 
        to_tsvector('english', coalesce(nume_strada, '')) || 
        to_tsvector('english', coalesce(nume_prenume, ''))|| 
        to_tsvector('english', coalesce(bloc, '')) ||
        to_tsvector('english', coalesce(apartament, '')) 
    ) @@ plainto_tsquery('english', '$q')

It works if I write in the variable $q all the text that appears in one of the columns present in the query. For example: cherry

I would like to write only: cher and return all rows fields in which it finds this string: "cher".

Erwin Brandstetter
  • 175,982
  • 27
  • 439
  • 600
CoderCoder42
  • 101
  • 1

1 Answers1

2

Postgres text search supports prefix matching:

SELECT *
FROM   renns
WHERE (
   to_tsvector('english', coalesce(numar_admin, '')) || 
   to_tsvector('english', coalesce(nume_strada, '')) || 
   to_tsvector('english', coalesce(nume_prenume, ''))|| 
   to_tsvector('english', coalesce(bloc, '')) ||
   to_tsvector('english', coalesce(apartament, '')) 
) @@ to_tsquery('simple', $q || ':*');

($q being a single word.)
This can use an index on your expression:

(to_tsvector('english', coalesce(numar_admin , '')) || 
 to_tsvector('english', coalesce(nume_strada , '')) || 
 to_tsvector('english', coalesce(nume_prenume, '')) || 
 to_tsvector('english', coalesce(bloc        , '')) ||
 to_tsvector('english', coalesce(apartament  , '')))

Using the 'simple' dictionary disables stemming. If you want stemming, use the 'english' dictionary like you had before.

"caisului 498:*" the "CAISULUI" string is from one column and the number from another column of the renns table

To pass multiple lexemes, apply 'english' stemming and do prefix matching for all of them:

@@ (to_tsquery('english', column_a || ':*') &&
    to_tsquery('english', column_b || ':*') -- more?   
   )

Detailed explanation:

Prefix matching matches at the start of lexemes. For any partial match, you can use LIKE or regular expression matches (~) in combination with a trigram index. Different approach! Requires a different query and a different index! See:

There are smart ways to integrate both. The manual has an example.

Erwin Brandstetter
  • 175,982
  • 27
  • 439
  • 600
  • I have an error: "SELECT * FROM renns WHERE ( to_tsvector('english', coalesce(numar_admin, '')) || to_tsvector('english', coalesce(nume_strada, '')) || to_tsvector('english', coalesce(nume_prenume, ''))|| to_tsvector('english', coalesce(bloc, '')) || to_tsvector('english', coalesce(apartament, '')) ) @@ to_tsquery('simple', 'caisului 498' || ':')" $q = "caisului 498" and error: syntax error in tsquery: "caisului 498:" :( the "CAISULUI" string is from one column and the number from another column of the renns table – CoderCoder42 Mar 31 '21 at 20:39
  • to_tsquery('simple', 'cher' || ':*') only works for a single lexeme. You tried to pass multiple. Which of the words is meant for prefix maching? All of them? – Erwin Brandstetter Mar 31 '21 at 20:50
  • I should be able to search for several words in $ q that correspond to several columns in the table from 1 to all if possible.

    I apologize for the poor explanation but I'm not very good at pgsql :(

    – CoderCoder42 Mar 31 '21 at 20:54
  • @CoderCoder42: I added some more for your case. – Erwin Brandstetter Mar 31 '21 at 21:05
  • @@ (to_tsquery('english', numar_admin || ':') && to_tsquery('english', nume_strada || ':');";

    I tried this, but I got an error: syntax error at or near ";" LINE 12: ... dmin || ': ') && to_tsquery ('english', nume_strada || ': '); ^ and where do I put $ q?

    – CoderCoder42 Mar 31 '21 at 21:15
  • @CoderCoder42: Missing closing parenthesis at the end. And this replaces $ q. – Erwin Brandstetter Mar 31 '21 at 21:19
  • This is @@ (to_tsquery('english', 'caisului 498' || ':') && to_tsquery('english', 'caisului 498' || ':') );" I try this way "caisului 498" when I write caisului in letters one by one it gives me good results but when I try to write 498 it doesn't return anything :( that 498 is in a different column than apricot – CoderCoder42 Apr 01 '21 at 05:26