# Dodaj repozytorium PGDG (oficjalne repo PostgreSQL)
# sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' # wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - # apt update # apt install postgresql-18-pgvector
Klient posgres
# su - postgres
# psql
Sprawdź czy pgvector jest zainstalowany na Twoim serwerze:
> SELECT * FROM pg_available_extensions WHERE name = 'vector'; name | default_version | installed_version | comment --------+-----------------+-------------------+------------------------------ vector | 0.8.2 | 0.8.2 | vector data type and ivfflat and hnsw access methods
Utworzenie usera i bazy danych
> CREATE USER rag_user WITH PASSWORD 'silne_haslo_tutaj'; > CREATE DATABASE rag_db OWNER rag_user; -- Połącz się z nową bazą > \c rag_db -- Zainstaluj rozszerzenie pgvector > CREATE EXTENSION IF NOT EXISTS vector; -- Nadaj uprawnienia > GRANT ALL PRIVILEGES ON DATABASE rag_db TO rag_user; > GRANT ALL PRIVILEGES ON SCHEMA public TO rag_user;
Tabela chunk-ów dokumentów
> CREATE TABLE document_chunks ( id BIGSERIAL PRIMARY KEY, brand_id INTEGER NOT NULL, source_type VARCHAR(50) NOT NULL, -- 'invoice', 'project', 'faq', itp. source_id INTEGER NOT NULL, -- id rekordu w MariaDB chunk_index INTEGER NOT NULL, -- numer fragmentu w dokumencie content TEXT NOT NULL, -- surowy tekst fragmentu embedding vector(1536), -- OpenAI text-embedding-3-small = 1536 wymiarów meta JSONB, -- dowolne dodatkowe dane (numer faktury, data, itp.) created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW() );
Indeksy
-- Indeks do szybkiego wyszukiwania wektorowego (cosine similarity) > CREATE INDEX ON document_chunks USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100); NOTICE: ivfflat index created with little data DETAIL: This will cause low recall. HINT: Drop the index until the table has more data. -- Indeksy pomocnicze > CREATE INDEX ON document_chunks (brand_id); > CREATE INDEX ON document_chunks (source_type, source_id);
Integracja PostgreSQL z CakePHP 5
// Ubuntu/Debian # apt install php-pgsql // sprawdź że jest aktywny # php -m | grep pgsql pdo_pgsql pgsql // Restart Apache # systemctl restart apache2
Połączenie w config/app.php:
return [
'Datasources' => [
'default' => [
'className' => Connection::class,
'driver' => Mysql::class,
'persistent' => false,
'timezone' => 'UTC',
....
],
'vector' => [
'className' => Connection::class,
'driver' => Postgres::class,
'persistent' => false,
'encoding' => 'utf8',
'timezone' => 'UTC',
],
],
];
Połączenie w config/app_local.php:
return [
'Encryption' => [
'key' => 'twój_klucz_base64',
],
'Datasources' => [
'default' => [
'host' => 'localhost',
'username' => 'mariadb_user',
'password' => 'mariadb_pass',
'database' => 'twoja_aplikacja',
],
'vector' => [
'host' => '127.0.0.1',
'port' => '5432',
'username' => 'rag_user',
'password' => 'silne_haslo_tutaj',
'database' => 'rag_db',
],
],
];
Model DocumentChunksTable wskazujący na PostgreSQL:
namespace App\Model\Table; use Cake\ORM\Table; class DocumentChunksTable extends Table { public static function defaultConnectionName(): string { return 'vector'; } public function initialize(array $config): void { parent::initialize($config); $this->setTable('document_chunks'); $this->setPrimaryKey('id'); $this->addBehavior('Timestamp', [ 'events' => [ 'Model.beforeSave' => [ 'created_at' => 'new', 'updated_at' => 'always', ], ], ]); } }
Test połączenia — dodaj tymczasowo w dowolnym kontrolerze w akcji:
$conn = \Cake\Datasource\ConnectionManager::get('vector'); $result = $conn->execute('SELECT version()')->fetch(); debug($result); exit;