migraciones para soportar el full text search
This commit is contained in:
@@ -52,27 +52,18 @@ for each row
|
||||
execute function public.fn_asignaturas_update_search_vector();
|
||||
|
||||
-- Paso 5
|
||||
update public.asignaturas
|
||||
set search_vector =
|
||||
setweight(
|
||||
to_tsvector('public.es_simple_unaccent', coalesce(nombre, '')),
|
||||
'A'
|
||||
)
|
||||
||
|
||||
setweight(
|
||||
to_tsvector('public.es_simple_unaccent', coalesce(codigo, '')),
|
||||
'A'
|
||||
)
|
||||
||
|
||||
setweight(
|
||||
to_tsvector('public.es_simple_unaccent', coalesce(datos, '{}'::jsonb)::text),
|
||||
'B'
|
||||
)
|
||||
||
|
||||
setweight(
|
||||
to_tsvector('public.es_simple_unaccent', coalesce(contenido_tematico, '[]'::jsonb)::text),
|
||||
'B'
|
||||
);
|
||||
create or replace function public.recalcular_vectores_asignaturas()
|
||||
returns void
|
||||
language sql
|
||||
as $$
|
||||
UPDATE public.asignaturas
|
||||
SET search_vector =
|
||||
setweight(to_tsvector('public.es_simple_unaccent', coalesce(nombre, '')), 'A') ||
|
||||
setweight(to_tsvector('public.es_simple_unaccent', coalesce(codigo, '')), 'A') ||
|
||||
setweight(to_tsvector('public.es_simple_unaccent', coalesce(datos, '{}'::jsonb)::text), 'B') ||
|
||||
setweight(to_tsvector('public.es_simple_unaccent', coalesce(contenido_tematico, '[]'::jsonb)::text), 'B')
|
||||
WHERE id IS NOT NULL;
|
||||
$$;
|
||||
|
||||
-- Paso 6
|
||||
create index if not exists asignaturas_search_vector_gin_idx
|
||||
@@ -117,7 +108,9 @@ $$;
|
||||
|
||||
-- Paso 8
|
||||
create or replace function public.search_asignaturas(
|
||||
p_search text,
|
||||
p_search text default '',
|
||||
p_facultad_id uuid default null,
|
||||
p_carrera_id uuid default null,
|
||||
p_plan_estudio_id uuid default null,
|
||||
p_limit integer default 20,
|
||||
p_offset integer default 0
|
||||
@@ -133,14 +126,19 @@ returns table (
|
||||
datos jsonb,
|
||||
contenido_tematico jsonb,
|
||||
estado public.estado_asignatura,
|
||||
rank real
|
||||
rank real,
|
||||
total_count bigint -- 👈 Total para la paginación del frontend
|
||||
)
|
||||
language sql
|
||||
language plpgsql
|
||||
stable
|
||||
as $$
|
||||
with q as (
|
||||
select public.build_asignaturas_prefix_tsquery(p_search) as tsq
|
||||
)
|
||||
declare
|
||||
v_tsq tsquery;
|
||||
begin
|
||||
-- 1. Construimos el query solo si hay texto
|
||||
v_tsq := public.build_asignaturas_prefix_tsquery(p_search);
|
||||
|
||||
return query
|
||||
select
|
||||
a.id,
|
||||
a.plan_estudio_id,
|
||||
@@ -152,16 +150,34 @@ as $$
|
||||
a.datos,
|
||||
a.contenido_tematico,
|
||||
a.estado,
|
||||
ts_rank(a.search_vector, q.tsq) as rank
|
||||
coalesce(ts_rank(a.search_vector, v_tsq), 0)::real as rank,
|
||||
count(*) OVER() as total_count -- 👈 Cuenta total ignorando el LIMIT
|
||||
from public.asignaturas a
|
||||
cross join q
|
||||
-- 2. JOINS para poder filtrar por la jerarquía superior
|
||||
left join public.planes_estudio p on a.plan_estudio_id = p.id
|
||||
left join public.carreras c on p.carrera_id = c.id
|
||||
where
|
||||
q.tsq is not null
|
||||
and a.search_vector @@ q.tsq
|
||||
-- 3. Si no hay búsqueda, trae todo. Si hay búsqueda, usa el FTS
|
||||
(v_tsq is null or a.search_vector @@ v_tsq)
|
||||
-- 4. Filtros jerárquicos dinámicos
|
||||
and (p_plan_estudio_id is null or a.plan_estudio_id = p_plan_estudio_id)
|
||||
and (p_carrera_id is null or p.carrera_id = p_carrera_id)
|
||||
and (p_facultad_id is null or c.facultad_id = p_facultad_id)
|
||||
order by
|
||||
rank desc,
|
||||
(case when v_tsq is not null then ts_rank(a.search_vector, v_tsq) else 0 end) desc,
|
||||
a.nombre asc
|
||||
limit p_limit
|
||||
offset p_offset;
|
||||
$$;
|
||||
end;
|
||||
$$;
|
||||
|
||||
-- Corrección de bug con triggers
|
||||
-- 1. Borramos la llave foránea estricta actual
|
||||
ALTER TABLE public.cambios_asignatura
|
||||
DROP CONSTRAINT cambios_asignatura_asignatura_id_fkey;
|
||||
|
||||
-- 2. La volvemos a crear, pero le decimos que espere al final de la transacción para validar
|
||||
ALTER TABLE public.cambios_asignatura
|
||||
ADD CONSTRAINT cambios_asignatura_asignatura_id_fkey
|
||||
FOREIGN KEY (asignatura_id) REFERENCES public.asignaturas(id)
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
||||
Reference in New Issue
Block a user