2

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

ERROR: syntax error at or near "||"

如果我用返回的单个 tsvector 尝试它,它工作正常setweight,如果我尝试将整个东西包装在另一个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 在这个查询中工作?

4

1 回答 1

2

假设列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省略关键字。逗号主要(见最后的链接)相当于 a 。LATERALCROSS JOIN

也可以为此工作:

SELECT ...
FROM   products
     , plainto_tsquery('awesome shirt') query
     , setweight(to_tsvector(coalesce(title, '')), 'A')  -- just another function
...

因此:

如果我使用 setweight 返回的单个 tsvector 尝试它,它工作正常

但是对于. _ _ _ 这些需要包含在需要显式关键字的语句中,以允许引用列表中的“横向”表。如上所示。或者,更短:setweight(...) || setweight(...)SELECTLATERALFROM

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 JOIN相关答案以及对和的更多解释LATERAL

于 2018-08-10T01:09:15.163 回答