tsvectors 的串联导致 Postgres 9.4.6 中的语法错误
Concatenation of tsvectors results in a syntax error in Postgres 9.4.6
在 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 在此查询中工作?
假设列 title
、description
等应该引用回 table 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 ...
是 FROM
子句中的隐式 CROSS JOIN LATERAL
。 functions 允许省略 LATERAL
关键字。逗号大部分(见末尾的 link)等同于 CROSS JOIN
.
也适用于此:
SELECT ...
FROM products
, plainto_tsquery('awesome shirt') query
, setweight(to_tsvector(coalesce(title, '')), 'A') -- just another function
...
因此:
It works fine if I try it with a single tsvector returned by setweight
但是相同的短语法不允许其他 表达式 喜欢 setweight(...) || setweight(...)
。这些需要包含在 SELECT
语句中,该语句需要显式 LATERAL
关键字以允许引用 FROM
列表中的 "lateral" table。就像上面演示的那样。或者,更短:
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
的更多解释的相关答案:
在 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 在此查询中工作?
假设列 title
、description
等应该引用回 table 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 ...
是 FROM
子句中的隐式 CROSS JOIN LATERAL
。 functions 允许省略 LATERAL
关键字。逗号大部分(见末尾的 link)等同于 CROSS JOIN
.
也适用于此:
SELECT ...
FROM products
, plainto_tsquery('awesome shirt') query
, setweight(to_tsvector(coalesce(title, '')), 'A') -- just another function
...
因此:
It works fine if I try it with a single tsvector returned by setweight
但是相同的短语法不允许其他 表达式 喜欢 setweight(...) || setweight(...)
。这些需要包含在 SELECT
语句中,该语句需要显式 LATERAL
关键字以允许引用 FROM
列表中的 "lateral" table。就像上面演示的那样。或者,更短:
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
的更多解释的相关答案: