postgresql Postgres中文本数组的tsvector生成列(超级数据库)

0yg35tkg  于 2023-02-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(112)

在Postgres(Supabase)中,我尝试从另一个包含短标题变体的文本数组的列自动生成一个列。
tsvector工作正常,正如预期的那样。另一种可能是使用array_to_tsvector不是一个选项,因为短标题文本数组不仅包含单个单词,还包含短标题(句子)的变体。

alter table "MOVIES"  
add column fts_short_title  
tsvector  GENERATED ALWAYS AS (  
to_tsvector('simple', 
array_to_string( title_short,' '::text)) 
 ) STORED;

但我得到了这个错误

Failed to run sql query: generation expression is not immutable

另一方面,我成功地为不同语言的JSONB添加了这样一列完整的标题

alter table "MOVIES"  
add column fts  
tsvector  GENERATED ALWAYS AS ( 
to_tsvector('simple', 
coalesce(title->>'en', '') || ' ' ||  
coalesce(title->>'de', '') || ' ' ||  
coalesce(title->>'it', '') || ' ' ||  
coalesce(title->>'fr', ''))
  ) STORED;

非常感谢您的任何提示和帮助。... SQL对我来说是相当新的,以前只在MongoDB中使用过,所以很抱歉我的问题。

watbbzwu

watbbzwu1#

您可以为其他不可变函数定义immutable Package 器。online demo

create or replace function array_to_string_immutable (
    arg text[], 
    separator text,
    null_string text default null) 
returns text immutable parallel safe language sql as $$
select array_to_string(arg,separator,null_string) $$;

alter table "MOVIES"  
add column fts_short_title  
tsvector  GENERATED ALWAYS AS (  
to_tsvector('simple', 
array_to_string_immutable( title_short,' '::text)) 
 ) STORED;
table "MOVIES";

虽然||操作符后面的textcat()函数是不可变的,但我非常肯定array_to_string()只是stablefor the same reason concat() is,因此您需要合理地小心使用此变通方法的位置。
您可以对另一列执行相同的操作,以使用concat_ws()并避免重复的||' '||coalesce()

create or replace function concat_ws_immutable (
    separator text,
    variadic arg text[]) 
returns text immutable parallel safe language sql as $$
select concat_ws(separator,variadic arg) $$;

alter table "MOVIES"  
add column fts  
tsvector  GENERATED ALWAYS AS ( 
 to_tsvector('simple',concat_ws_immutable(' ',title->>'en',title->>'de',title->>'it',title->>'fr'))
) STORED;

您还可以自由地做几乎任何您想要做的事情,但是您希望trigger after insert or update on "MOVIES"使用plpgsql function中的列。

相关问题