PostgreSQL不同版本之间全文索引搜索语法问题

问题描述 投票:0回答:1

几周前我们遇到了一个问题,我们的文本索引查询没有产生任何结果。这就是表达方式:

"test_column" @@ websearch_to_tsquery('english', "in_search_argument")

我们必须将其更新为:

"test_column_idx" @@ websearch_to_tsquery('english', "in_search_argument")

..其中

test_column_idx
定义为:

"test_column_idx" gin (to_tsvector('english'::regconfig, 'test_column'::text))

我们的服务器是 14.6(使用 psql 12.16)。

但是,我的开发环境对此有所抱怨:

sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedColumn) column p.test_column_idx does not exist

如果我将其改回使用该列(见上文;它在我们的开发环境中匹配得很好,即使我们的生产不匹配),它会再次工作。我们的开发环境使用server 14.9(我们在调试时缩小了版本之间的差距)和psql 15.4。

我应该使用什么语法来维护环境之间的兼容性?

添加(感谢@RichardHuxton):

因此,SQLAlchemy 在开发中将其创建为索引

"test_column_idx" gin (to_tsvector('english'::regconfig, 'test_column'::text))

SQLAlchemy 定义如下:

sqlalchemy.Index(
    'test_column_idx',

    sqlalchemy.sql.func.to_tsvector(
        sqlalchemy.literal(_TEXT_INDEX_LANGUAGE),
        'test_column'),

    postgresql_using='gin'),

当我实际部署它时,我已将其作为列手动添加到生产中:

test_column_idx      | tsvector          |           |          | generated always as (to_tsvector('english'::regconfig, test_column::text)) stored

那么,谁能建议我如何调整 SQLAlchemy 定义来创建列?

也就是说,我很困惑如何将索引语义安装为列和索引,以及首选其中之一的情况。我需要一些澄清。

谢谢你。

postgresql full-text-search psql inverted-index
1个回答
0
投票

问题很简单,但正确的流程也看似简单,而我所做的却微妙地偏离了。

不知何故,我们最终得到了一个文本向量列并且没有索引,我们的搜索函数使用了该列,并且为了让事情变得更加混乱,我无意中将此列命名为索引的预期名称(

idx_product_1
)。所以,当我寻找错误并审查搜索函数的定义时,我前几次都错过了这一点。

由于我们的工作完全按照预期进行(请参阅下面的问题所在),我们更加困惑了。我们终于明白了:

  1. 创建向量列是为了从普通数据自动填充
  2. 索引是从向量列创建的
  3. 查询是针对向量列执行的(不是直接针对索引执行的,这不正常,但我的电线交叉了;请参阅之前的评论/答案)
  4. 如果找到索引,向量列将透明地调用索引(像平常一样)
  5. 我们不需要需要索引来获得正确的结果。我们只需要它来优化搜索。
  6. 我们do需要对向量列执行文本查询,因为即使对原始列的文本查询不会失败,这样做时我们也会得到不正确的结果(通常不是错误的,但通常是不完整的) .

因此,我们这样做是为了自动填充 tsvector 列:

ALTER TABLE "products" ADD "style_name_vector" tsvector GENERATED ALWAYS AS (
     to_tsvector('simple', "internal_sku") || ' ' ||
     to_tsvector('english', "human_brand") || ' ' ||
     to_tsvector('simple', "style_id") || ' ' ||
     to_tsvector('english', "style_name") || ' ' ||
     to_tsvector('english', "gender") || ' ' ||
     to_tsvector('simple', shopify_product_id::varchar(255))
) STORED;

因为 tsvector 列是一个空格分隔的词向量表示列表,所以我们可以简单地连接一堆向量列,以便同时搜索所有这些列。这是之前设计中没有的优化。

创建索引:

CREATE INDEX "idx_product_1" ON "products" USING GIN("style_name_vector");

进行搜索(仅作为完整示例):

analytics=> select internal_sku, style_name from products where style_name_vector @@ websearch_to_tsquery('english', 'trail') limit 5;
 internal_sku |               style_name               
--------------+----------------------------------------
 TN100000926  | Mens Paramount Trail Convertible Pants
 RE000127387  | Trail 40
 PA000010810  | Womens Capilene Cool Trail Shirt
 SA000023516  | S Lab trail Running Shirt
 MA100000254  | Womens Vapor Trail Hoodie
© www.soinside.com 2019 - 2024. All rights reserved.