Postgresql – Make to_tsquery return OR of lexemes instead of AND

full-text-searchpostgresql

I'm using an dict_xsyn extension in postgres which returns multiple lexemes.

e.g.

CREATE EXTENSION dict_xsyn;

CREATE TEXT SEARCH DICTIONARY names_xsyn (TEMPLATE = 'xsyn_template');

CREATE SEARCH CONFIGURATION english_names ALTER MAPPING FOR asciiword, asciihword, hword_asciipart WITH names_xsyn, simple;

SELECT to_tsquery('english_names', 'ed')
-- returns: 'ed' & 'edward' & 'edwin' & 'edmond' 

I would prefer if to_tsquery returned ORed lexemes so that I could match to other variants. e.g.

-- returns: 'ed' | 'edward' | 'edwin' | 'edmond' 

I've tried ts_rewrite but that doesn't seem to support swapping logical operators.

–Edit
I'm doing this so that I can match partially matching sets.
e.g.
I want ed to match edward and edwin, but I don't want edward to match edwin. Here are my lexemes:

ed -> ed, edward, edwin

edward -> ed, edward

edwin -> ed, edwin

Using those lexmes to match ed to edward will only work with an or.

"ed, edward" @@ "ed | edward | edwin" will work

"ed, edward" @@ "ed & edward & edwin" won't work

Best Answer

I don't know how to do that exclusively with dict_xsyn, other than by manipulating the output as text and the converting back, but I don't think you want to do that anyway. I think it would be a performance nightmare.

You probably want to reverse this so that all nicknames get canonicalized down to a single variant, rather than exploded out to all variants.

alter TEXT SEARCH DICTIONARY names_xsyn (KEEPORIG=true, MATCHORIG=true,
  KEEPSYNONYMS=false, MATCHSYNONYMS=true);

But I have no idea why that is not the default, so perhaps I just fundamentally misunderstand the point of that extension.

Both the tsquery and the tsvector would be canonicalized the same way, so a query with 'bobbie' would match a document with 'robert' and vice versa.

But perhaps I just don't understand your end goal. You can do what you are directly asking for with ts_rewrite, but it is not done by building on top of dict_xsyn. Is the example involving supernovae & crab not just what you want?