在SQL查询中连接setweight中的tsvectors时,会引发语法错误:

ERROR: syntax error at or near "||"

如果我尝试使用setweight返回的单个tsvector,并且如果我尝试将整个东西包装到另一个to_tsvector调用中,那么它会出错,原因是没有to_tsvector(tsvector)函数,因此连接实际上正在形成一个tsvector。
SELECT *, ts_rank_cd(textsearch, query) AS score
FROM products, plainto_tsquery('awesome shirt') query,
   setweight(to_tsvector(coalesce(title, '')), 'A') ||
   setweight(to_tsvector(coalesce(description, '')), 'B') ||
   setweight(to_tsvector(coalesce(tags, '')), 'C') ||
   setweight(to_tsvector(coalesce(vendor, '')), 'D') textsearch
WHERE shop_url='somedomain.com' AND query @@ textsearch
ORDER BY score DESC
LIMIT 20 OFFSET 0;

我试过将它包装成一个子查询,但这会使它成为一个记录,这会导致ts_rank_cd出现问题,因为它期望textsearch是tsvector类型。如何使这个特定的tsvector在这个查询中工作?

最佳答案

假设列titledescription等应该返回到表products。。。
您看到的语法错误与文本搜索本身无关。这应该有效:

SELECT *, ts_rank_cd(textsearch, query) AS score
FROM   products
CROSS  JOIN LATERAL plainto_tsquery('awesome shirt') query
CROSS  JOIN LATERAL (
   SELECT setweight(to_tsvector(coalesce(title      , '')), 'A')
       || setweight(to_tsvector(coalesce(description, '')), 'B')
       || setweight(to_tsvector(coalesce(tags       , '')), 'C')
       || setweight(to_tsvector(coalesce(vendor     , '')), 'D')
   ) ts (textsearch)
WHERE  ...

为什么?
因为:
SELECT ...
FROM   products, plainto_tsquery('awesome shirt') query ...

CROSS JOIN LATERAL子句中的隐式FROM。函数允许省略LATERAL关键字。逗号大部分(见末尾的链接)相当于aCROSS JOIN
也会起作用的:
SELECT ...
FROM   products
     , plainto_tsquery('awesome shirt') query
     , setweight(to_tsvector(coalesce(title, '')), 'A')  -- just another function
...

因此:
如果我用setweight返回的一个tsvector来尝试,它就可以工作了
但其他表达式(如setweight(...) || setweight(...))不允许使用相同的短语法。它们需要包装在一个SELECT语句中,该语句需要显式的LATERAL关键字来允许引用FROM列表中的“silateral”表。就像上面演示的那样。或者,更短:
SELECT *, ts_rank_cd(textsearch, query) AS score
FROM   products
     , plainto_tsquery('awesome shirt') query
     , LATERAL (
   SELECT setweight(to_tsvector(coalesce(title      , '')), 'A')
       || setweight(to_tsvector(coalesce(description, '')), 'B')
       || setweight(to_tsvector(coalesce(tags       , '')), 'C')
       || setweight(to_tsvector(coalesce(vendor     , '')), 'D')
   ) ts (textsearch)
WHERE  ...

关于CROSS JOINLATERAL的更多解释的相关答案:
What does [FROM x, y] mean in Postgres?

关于sql - tsvector的串联导致Postgres 9.4.6中的语法错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51774846/

10-11 02:16