Postgresql,tsquery 不适用于部分字符串



我使用postgres的tsquery函数来搜索可能包含多种语言的字母和数字的字段。似乎在任何情况下,搜索都会工作到搜索短语的一部分,并停止工作,直到你写出完整的短语。

例如:当搜索项为"15339"时,搜索名称"15339"会输出右侧行,但如果是"153"则不会。

搜索Al Alamya时,如果单词是"Al-",它会起作用并返回行,但在之后添加字母,例如,"Al-alam"在我写完全名("Al-Alamya"(之前不会返回。

我的查询:

SELECT *
FROM (SELECT DISTINCT ON ("consumer_api_spot"."id") "consumer_api_spot"."id",
"consumer_api_spot"."name",
FROM "consumer_api_spot"
INNER JOIN "consumer_api_account" ON ("consumer_api_spot"."account_id" = "consumer_api_account"."id")
INNER JOIN "users_user" ON ("consumer_api_account"."id" = "users_user"."account_id")
WHERE (
users_user.id = 53 AND consumer_api_spot.active
AND
"consumer_api_spot"."vectorized_name" @@ tsquery('153')
)
GROUP BY "consumer_api_spot"."id"
) AS "Q"
LIMIT 50 OFFSET 0

如果查看文档,您会发现有关可以指定为tsquery的内容的更多信息。它们支持分组,使用布尔运算进行组合,还支持前缀,这可能是您想要的。文档中的一个示例:

此外,tsquery中的词法可以用*标记,以指定前缀匹配:

SELECT 'super:*'::tsquery;

此查询将匹配tsvector中以"super"开头的任何单词。

因此,在查询中,您应该将tsquery('153')的部分修改为tsquery('153:*')

Btw。我不知道您是如何构建数据库模式的,但您可以使用GIN索引为列添加tsvector索引。我假设您从"consumer_api_spot"."name"列生成"consumer_api_spot"."vectorized_name"列。如果是这种情况,您可以为该列创建一个tsvector索引,如下所示:

CREATE INDEX gin_name on consumer_api_spot using gin (to_tsvector('english',name))

然后你可以更改这个查询:

"consumer_api_spot"."vectorized_name" @@ tsquery('153')

进入这个:

to_tsvector('english', "consumer_api_spot"."name") @@ to_tsquery('english', '153:*')

并获得潜在的速度优势,因为查询将使用索引。

关于'english'的注意事项:创建索引时不能省略语言,但它不会对其他语言的查询或带数字的查询产生影响。但是,请注意,创建索引和执行查询的语言必须相同,才能使PostgreSQL使用索引。

最新更新