Zpět na domů

Hibridní vyhledávání v PostgreSQL | Nastavení VectorChord

Článek popisuje nastavení infrastruktury pro hibridní vyhledávání s použitím PostgreSQL a VectorChord. Jsou zváženy návrh tabulek, automatická instalace rozšíření a organizace pipelines zpracování dat. Materiál je určen pro vývojáře vytvářející pokročilé vyhledávací systémy.

Jak nastavit hibridní vyhledávání v PostgreSQL s VectorChord
Advertisement 728x90

Hybridní vyhledávání na PostgreSQL a VectorChord: nastavení infrastruktury

Hybridní vyhledávání, které kombinuje vektorovou a plnotextovou metodu, se stává standardem pro moderní vyhledávací systémy. V tomto článku podrobně rozebereme nastavení infrastruktury na bázi PostgreSQL a VectorChord – řešení, které zjednodušuje implementaci hybridního vyhledávání bez nutnosti ruční instalace rozšíření a složité konfigurace.

Příprava prostředí: Docker a PostgreSQL

Pro start potřebujeme kontejnerizované prostředí. Použijeme Docker Compose k nasazení PostgreSQL s předinstalovanými rozšířeními VectorChord. Upozorňujeme: v konfiguraci explicitně neuvádíme rozšíření – budou přidána automaticky při prvním připojení přes VechordRegistry.

Příklad souboru docker-compose-dev.yml:

Google AdInline article slot
services:
  postgres:
    image: tensorchord/vchord-suite:pg18-latest
    environment:
      POSTGRES_DB: ${DB__NAME}
      POSTGRES_USER: ${DB__USER}
      POSTGRES_PASSWORD: ${DB__PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB__USER} -d ${DB__NAME}"]
      interval: 5s
      timeout: 5s
      retries: 5
volumes:
  pgdata:

Klíčový moment: obrázek tensorchord/vchord-suite již obsahuje všechny potřebné komponenty, ale rozšíření se aktivují až při prvním volání přes VechordRegistry. To umožňuje vyhnout se ruční konfiguraci a zaručuje kompatibilitu verzí.

Návrh tabulek pro hybridní vyhledávání

Struktura dat je postavena na třech tabulkách. Základní tabulka BaseTable obsahuje společná pole:

from datetime import datetime, timezone
from functools import partial
import msgspec
from psycopg.types.json import Jsonb
from vechord import Table

class BaseTable(Table, kw_only=True):
    metadata: Jsonb
    created_at: datetime = msgspec.field(
        default_factory=partial(datetime.now, timezone.utc))
    updated_at: datetime = msgspec.field(
        default_factory=partial(datetime.now, timezone.utc))

Pole metadata ukládá libovolná data ve formátu JSONB a časové značky se aktualizují automaticky při vytvoření záznamu. Upozorňujeme: updated_at se neaktualizuje automaticky při změně záznamu – to je třeba udělat ručně v metodách aktualizace.

Google AdInline article slot

Tabulka dokumentů Document:

import msgspec
from vechord.spec import PrimaryKeyUUID
from .base import BaseTable

class Document(BaseTable, kw_only=True):
    uid: PrimaryKeyUUID = msgspec.field(default_factory=PrimaryKeyUUID.factory)
    title: str
    text: str

Pro primární klíč se používá UUID. Tabulka chunků Chunk je spojena s dokumentem přes cizí klíč:

from vechord.spec import ForeignKey, Keyword, PrimaryKeyUUID, Vector

class Chunk(BaseTable, kw_only=True):
    uid: PrimaryKeyUUID = msgspec.field(default_factory=PrimaryKeyUUID.factory)
    doc_id: Annotated[UUID, ForeignKey[Document.uid]]
    content: str
    content_tsv: Keyword
    embedding: DenseVector
    chunk_index: int

Zde je content_tsv určené pro plnotextové vyhledávání (BM25) a embedding ukládá vektorovou reprezentaci chunku. Cizí klíč doc_id automaticky realizuje kaskádové mazání.

Google AdInline article slot

Důležité: pokus vyjmout uid do základní třídy vede k chybě, protože ForeignKey hledá pole v BaseTable, nikoli v konkrétní tabulce. Proto se primární klíč duplikuje v každé tabulce.

VechordRegistry: centralizované řízení DB

Třída VechordRegistry slouží jako jednotné rozhraní pro práci s databází. Automatizuje:

  • Instalaci rozšíření (vchord, vchord_bm25, pg_tokenizer)
  • Vytváření tabulek a tokenizátorů
  • Provádění CRUD operací a vyhledávání

Inicializace:

from vechord import VechordRegistry
from core import settings
from .document import Document
from .doc_chunk import Chunk

vr = VechordRegistry(
    namespace=settings.db.namespace,
    url=settings.db.db_url,
    tables=[Document, Chunk]
)

Při prvním použití (v kontextu async with vr:) se spustí metoda init_extension, která instaluje rozšíření a nastavuje search_path. To eliminuje nutnost ruční konfigurace a minimalizuje chyby.

Příklad použití pro vložení dokumentu:

async with vr:
    doc = Document(title='Note', text='Some text', metadata=Jsonb({}))
    await vr.insert(doc)

Po provedení tohoto kódu se v DB objeví všechna potřebná rozšíření, tabulky a záznam.

Potrubí zpracování dat

Pro složité operace, jako je vytvoření dokumentu s následným chunkováním, se používá VechordPipeline. Umožňuje spojit několik kroků do konvejéru, kde každý stupeň automaticky ukládá výsledky do DB.

Krok 1: Vytvoření dokumentu. Dekorátor @vr.inject(output=Document) zaručuje uložení objektu:

@vr.inject(output=Document)
async def _create_document(doc_data: DocumentCreate) -> Document:
    doc = Document(
        title=doc_data.title,
        text=doc_data.text,
        metadata=Jsonb(doc_data.metadata)
    )
    return doc

Krok 2: Generování chunků. Přijímá data z tabulky Document a vrací seznam chunků:

@vr.inject(input=Document, output=Chunk)
async def create_chunks(uid: UUID, text: str) -> list[Chunk]:
    chunks = await _chunker.segment(text)
    return [
        Chunk(
            doc_id=uid,
            content=chunk,
            content_tsv=Keyword(chunk),
            embedding=DenseVector(await _embedder.vectorize_chunk(chunk)),
            metadata=Jsonb({}),
            chunk_index=i
        )
        for i, chunk in enumerate(chunks, start=1)
    ]

Sestavení potrubí:

from db_models import vr
from .utils import create_chunks, create_document

class DocumentService:
    async def create_document(self, doc_data: DocumentCreate):
        pipeline = vr.pipeline(
            _create_document,
            create_chunks
        )
        await pipeline(doc_data)

Tento přístup zajišťuje atomaritu operací a minimalizuje počet volání do DB.

Co je důležité: klíčové aspekty implementace

Při zavádění hybridního vyhledávání na bázi VectorChord obraťte pozornost na:

  • Automatická inicializace rozšíření: VechordRegistry instaluje všechny potřebné komponenty při prvním připojení, což zjednodušuje nasazení.
  • Struktura tabulek: rozdělení na dokumenty a chunky je klíčové pro efektivní vyhledávání; cizí klíče zajišťují integritu dat.
  • Potrubí zpracování: použití VechordPipeline umožňuje zapouzdřit složité operace a zaručit konzistenci dat.

Tyto prvky tvoří základ pro škálovatelný vyhledávací systém, který kombinuje přesnost vektorového vyhledávání a flexibilitu plnotextového.

— Editorial Team

Advertisement 728x90

Číst dál