idea_world_labDEV JOURNAL
domingo, 28 de junio de 2026

Alternativa A: Mantener el full-text de PostgreSQL actual

Flujo

raw chunkText
  -> plainto_tsquery
  -> search_tsv @@ query
  -> ts_rank_cd
  -> top JSONL devolución

Ventajas

  • Ya está implementado.
  • Es posible solo con PostgreSQL.
  • La infraestructura es simple.
  • search_tsv encaja directamente con la tabla que ya lo tiene.

Desventajas

  • No es BM25.
  • Es débil con fragmentos de código largos.
  • La condición generada por plainto_tsquery puede volverse excesivamente restrictiva.
  • Hay mucho ruido de tokens de código.
  • No permite búsqueda semántica.
  • Si la división del fragmento cambia ligeramente, pueden aparecer resultados nulos.

Problemas esperados en el fragmento de referencia

En el fragmento de referencia se incluyen los siguientes tokens de una sola vez.

func
process
delta
velocity
vector2
zero
input
is_action_pressed
move_right
move_left
normalized
animatedsprite2d
play
stop
position
clamp
screen_size

Si todos estos tokens no están simultáneamente dentro de una fila JSONL, los resultados de búsqueda pueden omitirse.

Simulación PoC

Supongamos que el chunk de referencia se envía tal cual a /api/retrieve.

Entrada:

chunkText = cuerpo completo de la función _process(delta)

El método actual convierte esta entrada en plainto_tsquery('simple', chunkText).

Tipo de consulta esperado:

func & process & delta & var & velocity & vector2 & zero
& input & is_action_pressed & move_right & move_left
& length & normalized & speed & animatedsprite2d
& play & stop & position & clamp & screen_size

En ese caso, si el documento real relacionado está dividido en dos fragmentos como se muestra a continuación, surge un problema.

docs chunk A:
  Input.is_action_pressed("move_right")
  Input.is_action_pressed("move_left")
  velocity.normalized() * speed
  $AnimatedSprite2D.play()
  $AnimatedSprite2D.stop()

docs chunk B:
  position += velocity * delta
  position = position.clamp(Vector2.ZERO, screen_size)

Si una persona lo ve, A y B están relacionados.

Sin embargo, si la consulta de texto completo exige demasiados tokens al mismo tiempo, puede suceder lo siguiente.

docs chunk A:
  animatedsprite2d = presente
  is_action_pressed = presente
  move_left/move_right = presente
  clamp = ausente
  screen_size = ausente
  position.clamp = ausente
  => la consulta no satisface completamente

docs chunk B:
  clamp = presente
  screen_size = presente
  position = presente
  animatedsprite2d = ausente o débil
  move_left/move_right = ausente
  is_action_pressed = ausente
  => la consulta no satisface completamente

Forma visible de fracaso:

Resultados de búsqueda 0  
O devolver solo un fragmento muy pequeño

En este método, es difícil distinguir si el fallo de búsqueda se debe a “falta de base en el documento” o a “fallo por condiciones de consulta demasiado restrictivas”.

Registro a verificar en la PoC

Al probar esta alternativa, no se debe observar solo el resultado.

Se deben mostrar los siguientes valores.

1. raw chunkText  
2. consulta creada con `plainto_tsquery`  
3. lista de tokens incluidos en la consulta  
4. número de filas devueltas  
5. si es 0, qué token la hizo demasiado restrictiva

Observación esperada:

Cuanto más largo sea el raw chunk, más larga será la consulta,  
si los documentos relacionados están divididos en varios chunks, los resultados se pierden.

Juicio

Puede usarse como línea base de PoC  
Como estrategia de búsqueda final, candidato a eliminación

El juicio de la nota original se acerca a “es correcto rehacerlo”.