Ruby on rails PostgreSQL:如何绕过ts_向量大小限制?

Ruby on rails PostgreSQL:如何绕过ts_向量大小限制?,ruby-on-rails,postgresql,rails-postgresql,pg-search,tsvector,Ruby On Rails,Postgresql,Rails Postgresql,Pg Search,Tsvector,我正在使用pg\u search gem在Rails应用程序中创建搜索。然而,其中一个表有一个Textdatatype字段,它的内容恰好比通常的要大一点 现在,当我需要为text列设置tsvector列时,由于文本字段大小与tsvector大小的不同,我面临一些限制 错误:字符串对于tsvector太长(5068741字节,最大1048575字节) 在SQL触发器中创建tsvector列时,是否有任何方法可以确定跳过更大的Text字段的条件,以执行以下操作: CREATE FUNCTION es

我正在使用
pg\u search gem
在Rails应用程序中创建搜索。然而,其中一个表有一个
Text
datatype字段,它的内容恰好比通常的要大一点

现在,当我需要为
text
列设置
tsvector列时,由于文本字段大小与tsvector大小的不同,我面临一些限制

错误:字符串对于tsvector太长(5068741字节,最大1048575字节)

SQL
触发器中创建tsvector列时,是否有任何方法可以确定跳过更大的
Text
字段的条件,以执行以下操作:

CREATE FUNCTION essays_tsv_trigger_fn() RETURNS trigger AS $$
begin
    new.tsv_body_text := to_tsvector('english', left(new.body_text, 4*1024*1024));
    return new;
end
$$ LANGUAGE plpgsql;

CREATE TRIGGER essays_tsv_trigger BEFORE INSERT OR UPDATE
    ON essays FOR EACH ROW EXECUTE FUNCTION essays_tsv_trigger_fn();
CREATE FUNCTION essays_tsv_trigger_fn() RETURNS trigger AS $$
begin
    if length(new.body_text) <= 4*1024*1024 then
        new.tsv_body_text := to_tsvector('english', new.body_text);
    end if;
  return new;
end
$$ LANGUAGE plpgsql;
伪代码:

execute(<<-TRIGGERSQL)
CREATE OR REPLACE FUNCTION public.essays_before_insert_update_row_tr()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$
BEGIN
    If (SELECT LEN(body_text) FROM essays) <= 1048575
      new.tsv_body_text := to_tsvector('pg_catalog.english', coalesce(new.body_text,''));
      RETURN NEW;
    End
END;
$function$
  TRIGGERSQL

  # no candidate create_trigger statement could be found, creating an adapter-specific one
  execute("CREATE TRIGGER essays_before_insert_update_row_tr BEFORE INSERT OR UPDATE ON \"essays\" FOR EACH ROW EXECUTE PROCEDURE essays_before_insert_update_row_tr()")

execute(一个简单的解决方法是使用截断的文本值调用
to_tsvector()

CREATE FUNCTION essays_tsv_trigger_fn() RETURNS trigger AS $$
begin
    new.tsv_body_text := to_tsvector('english', left(new.body_text, 4*1024*1024));
    return new;
end
$$ LANGUAGE plpgsql;

CREATE TRIGGER essays_tsv_trigger BEFORE INSERT OR UPDATE
    ON essays FOR EACH ROW EXECUTE FUNCTION essays_tsv_trigger_fn();
CREATE FUNCTION essays_tsv_trigger_fn() RETURNS trigger AS $$
begin
    if length(new.body_text) <= 4*1024*1024 then
        new.tsv_body_text := to_tsvector('english', new.body_text);
    end if;
  return new;
end
$$ LANGUAGE plpgsql;
这会将文档内容截断为4 MiB,这对于许多文档集合来说应该足够有用。与其忽略“过长”的文档,不如至少包含其中的一部分。根据我的经验,4 MiB对于技术英语文档非常有效。根据实际使用的词汇表的大小,如果使用较大的值(如10 MiB)运行

如果您真的想忽略太长的文档,可以使用如下If语句保护
to_tsvector()
赋值:

CREATE FUNCTION essays_tsv_trigger_fn() RETURNS trigger AS $$
begin
    new.tsv_body_text := to_tsvector('english', left(new.body_text, 4*1024*1024));
    return new;
end
$$ LANGUAGE plpgsql;

CREATE TRIGGER essays_tsv_trigger BEFORE INSERT OR UPDATE
    ON essays FOR EACH ROW EXECUTE FUNCTION essays_tsv_trigger_fn();
CREATE FUNCTION essays_tsv_trigger_fn() RETURNS trigger AS $$
begin
    if length(new.body_text) <= 4*1024*1024 then
        new.tsv_body_text := to_tsvector('english', new.body_text);
    end if;
  return new;
end
$$ LANGUAGE plpgsql;
CREATE FUNCTION\u tsv\u trigger\u fn()将触发器返回为$$
开始
如果长度(新的.body\u文本)