tsvector的串联导致Postgres 9.4.6中的语法错误

时间:2018-08-09 19:53:08

标签: sql postgresql postgresql-9.4 lateral-join

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

ERROR: syntax error at or near "||"

如果我使用由setweight返回的单个tsvector进行尝试,则效果很好,如果我尝试将整个内容包装在另一个to_tsvector调用中,则会出错,原因是没有{ {1}}函数,因此串联确实形成了tsvector。

to_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属于tsvector类型。如何在查询中使用此关联的tsvector?

1 个答案:

答案 0 :(得分:1)

假定列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关键字。而且逗号大部分(参见结尾处的链接)等效于CROSS 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列表中的“横向”表。就像上面展示的。或更短一点:

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的更多解释的相关答案: