pgvector support for PHP
197
stars
195
commits
PHP
primary language
Jul 9, 2026
updated
pgvector support for PHP
Supports Laravel, Symfony, Doctrine, and PgSql
Follow the instructions for your database library:
Or check out some examples:
COPYNote: The Laravel AI SDK also supports the vector type
Install the package
composer require pgvector/pgvector
Enable the extension
php artisan vendor:publish --tag="pgvector-migrations"
php artisan migrate
You can now use the vector, halfvec, bit, and sparsevec types in future migrations
Schema::create('items', function (Blueprint $table) {
$table->vector('embedding', 3);
});
Update your model
use Pgvector\Laravel\Vector;
class Item extends Model
{
use HasNeighbors;
protected $casts = ['embedding' => Vector::class];
}
Insert a vector
$item = new Item();
$item->embedding = [1, 2, 3];
$item->save();
Get the nearest neighbors to a record
use Pgvector\Laravel\Distance;
$neighbors = $item->nearestNeighbors('embedding', Distance::L2)->take(5)->get();
Also supports InnerProduct, Cosine, L1, Hamming, and Jaccard distance
Get the nearest neighbors to a vector
$neighbors = Item::query()->nearestNeighbors('embedding', [1, 2, 3], Distance::L2)->take(5)->get();
Get the distances
$neighbors->pluck('neighbor_distance');
Add an approximate index in a migration
public function up()
{
DB::statement('CREATE INDEX my_index ON items USING hnsw (embedding vector_l2_ops)');
// or
DB::statement('CREATE INDEX my_index ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)');
}
public function down()
{
DB::statement('DROP INDEX my_index');
}
Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
Install the package
composer require pgvector/pgvector
Register the types and distance functions in config/packages/doctrine.yaml
doctrine:
dbal:
types:
vector: Pgvector\Doctrine\VectorType
halfvec: Pgvector\Doctrine\HalfVectorType
bit: Pgvector\Doctrine\BitType
sparsevec: Pgvector\Doctrine\SparseVectorType
orm:
dql:
numeric_functions:
l2_distance: Pgvector\Doctrine\L2Distance
max_inner_product: Pgvector\Doctrine\MaxInnerProduct
cosine_distance: Pgvector\Doctrine\CosineDistance
l1_distance: Pgvector\Doctrine\L1Distance
hamming_distance: Pgvector\Doctrine\HammingDistance
jaccard_distance: Pgvector\Doctrine\JaccardDistance
Create a migration to enable the extension
php bin/console doctrine:migrations:generate
And update it
public function up(Schema $schema): void
{
$this->addSql('CREATE EXTENSION vector');
}
public function down(Schema $schema): void
{
$this->addSql('DROP EXTENSION vector');
}
Migrate
php bin/console doctrine:migrations:migrate
Update your entity
use Pgvector\Vector;
#[ORM\Entity(repositoryClass: ItemRepository::class)]
class Item
{
#[ORM\Column(type: 'vector', length: 3)]
private ?Vector $embedding = null;
public function getEmbedding(): ?Vector
{
return $this->embedding;
}
public function setEmbedding(Vector $embedding): static
{
$this->embedding = $embedding;
return $this;
}
}
Migrate
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Insert a vector
$item = new Item();
$item->setEmbedding(new Vector([1, 2, 3]));
$entityManager->persist($item);
$entityManager->flush();
Get the nearest neighbors to a vector
$neighbors = $entityManager->createQuery('SELECT i FROM App\Entity\Item i ORDER BY l2_distance(i.embedding, ?1)')
->setParameter(1, new Vector([1, 2, 3]))
->setMaxResults(5)
->getResult();
Also supports max_inner_product, cosine_distance, l1_distance, hamming_distance, and jaccard_distance
Install the package
composer require pgvector/pgvector
Register the types and distance functions
use Pgvector\Doctrine\PgvectorSetup;
PgvectorSetup::registerTypes($entityManager);
Enable the extension
$entityManager->getConnection()->executeStatement('CREATE EXTENSION IF NOT EXISTS vector');
Update your entity
use Pgvector\Vector;
#[ORM\Entity]
class Item
{
#[ORM\Column(type: 'vector', length: 3)]
private Vector $embedding;
public function setEmbedding(Vector $embedding): void
{
$this->embedding = $embedding;
}
}
Insert a vector
$item = new Item();
$item->setEmbedding(new Vector([1, 2, 3]));
$entityManager->persist($item);
$entityManager->flush();
Get the nearest neighbors to a vector
$neighbors = $entityManager->createQuery('SELECT i FROM Item i ORDER BY l2_distance(i.embedding, ?1)')
->setParameter(1, new Vector([1, 2, 3]))
->setMaxResults(5)
->getResult();
Also supports max_inner_product, cosine_distance, l1_distance, hamming_distance, and jaccard_distance
Enable the extension
pg_query($db, 'CREATE EXTENSION IF NOT EXISTS vector');
Create a table
pg_query($db, 'CREATE TABLE items (embedding vector(3))');
Insert a vector
use Pgvector\Vector;
$embedding = new Vector([1, 2, 3]);
pg_query_params($db, 'INSERT INTO items (embedding) VALUES ($1)', [$embedding]);
Get the nearest neighbors to a vector
$embedding = new Vector([1, 2, 3]);
$result = pg_query_params($db, 'SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5', [$embedding]);
Add an approximate index
pg_query($db, 'CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)');
// or
pg_query($db, 'CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)');
See a full example
Create a vector from an array
$vec = new Vector([1, 2, 3]);
Get an array
$arr = $vec->toArray();
Create a half vector from an array
$vec = new HalfVector([1, 2, 3]);
Get an array
$arr = $vec->toArray();
Create a sparse vector from an indexed array
$vec = new SparseVector([1, 0, 2, 0, 3, 0]);
Or an associative array of non-zero elements
$elements = [0 => 1, 2 => 2, 4 => 3];
$vec = new SparseVector($elements, 6);
Note: Indices start at 0
Get the number of dimensions
$dim = $vec->dimensions();
Get the indices of non-zero elements
$indices = $vec->indices();
Get the values of non-zero elements
$values = $vec->values();
Get an array
$arr = $vec->toArray();
View the changelog
Everyone is encouraged to help improve this project. Here are a few ways you can help:
To get started with development:
git clone https://github.com/pgvector/pgvector-php.git
cd pgvector-php
composer install
createdb pgvector_php_test
composer test
To run an example:
cd examples/loading
composer install
createdb pgvector_example
php example.php
PHP
100.0%
pgvector support for PHP
197
stars
195
commits
PHP
primary language
Jul 9, 2026
updated
pgvector support for PHP
Supports Laravel, Symfony, Doctrine, and PgSql
Follow the instructions for your database library:
Or check out some examples:
COPYNote: The Laravel AI SDK also supports the vector type
Install the package
composer require pgvector/pgvector
Enable the extension
php artisan vendor:publish --tag="pgvector-migrations"
php artisan migrate
You can now use the vector, halfvec, bit, and sparsevec types in future migrations
Schema::create('items', function (Blueprint $table) {
$table->vector('embedding', 3);
});
Update your model
use Pgvector\Laravel\Vector;
class Item extends Model
{
use HasNeighbors;
protected $casts = ['embedding' => Vector::class];
}
Insert a vector
$item = new Item();
$item->embedding = [1, 2, 3];
$item->save();
Get the nearest neighbors to a record
use Pgvector\Laravel\Distance;
$neighbors = $item->nearestNeighbors('embedding', Distance::L2)->take(5)->get();
Also supports InnerProduct, Cosine, L1, Hamming, and Jaccard distance
Get the nearest neighbors to a vector
$neighbors = Item::query()->nearestNeighbors('embedding', [1, 2, 3], Distance::L2)->take(5)->get();
Get the distances
$neighbors->pluck('neighbor_distance');
Add an approximate index in a migration
public function up()
{
DB::statement('CREATE INDEX my_index ON items USING hnsw (embedding vector_l2_ops)');
// or
DB::statement('CREATE INDEX my_index ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)');
}
public function down()
{
DB::statement('DROP INDEX my_index');
}
Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance
Install the package
composer require pgvector/pgvector
Register the types and distance functions in config/packages/doctrine.yaml
doctrine:
dbal:
types:
vector: Pgvector\Doctrine\VectorType
halfvec: Pgvector\Doctrine\HalfVectorType
bit: Pgvector\Doctrine\BitType
sparsevec: Pgvector\Doctrine\SparseVectorType
orm:
dql:
numeric_functions:
l2_distance: Pgvector\Doctrine\L2Distance
max_inner_product: Pgvector\Doctrine\MaxInnerProduct
cosine_distance: Pgvector\Doctrine\CosineDistance
l1_distance: Pgvector\Doctrine\L1Distance
hamming_distance: Pgvector\Doctrine\HammingDistance
jaccard_distance: Pgvector\Doctrine\JaccardDistance
Create a migration to enable the extension
php bin/console doctrine:migrations:generate
And update it
public function up(Schema $schema): void
{
$this->addSql('CREATE EXTENSION vector');
}
public function down(Schema $schema): void
{
$this->addSql('DROP EXTENSION vector');
}
Migrate
php bin/console doctrine:migrations:migrate
Update your entity
use Pgvector\Vector;
#[ORM\Entity(repositoryClass: ItemRepository::class)]
class Item
{
#[ORM\Column(type: 'vector', length: 3)]
private ?Vector $embedding = null;
public function getEmbedding(): ?Vector
{
return $this->embedding;
}
public function setEmbedding(Vector $embedding): static
{
$this->embedding = $embedding;
return $this;
}
}
Migrate
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Insert a vector
$item = new Item();
$item->setEmbedding(new Vector([1, 2, 3]));
$entityManager->persist($item);
$entityManager->flush();
Get the nearest neighbors to a vector
$neighbors = $entityManager->createQuery('SELECT i FROM App\Entity\Item i ORDER BY l2_distance(i.embedding, ?1)')
->setParameter(1, new Vector([1, 2, 3]))
->setMaxResults(5)
->getResult();
Also supports max_inner_product, cosine_distance, l1_distance, hamming_distance, and jaccard_distance
Install the package
composer require pgvector/pgvector
Register the types and distance functions
use Pgvector\Doctrine\PgvectorSetup;
PgvectorSetup::registerTypes($entityManager);
Enable the extension
$entityManager->getConnection()->executeStatement('CREATE EXTENSION IF NOT EXISTS vector');
Update your entity
use Pgvector\Vector;
#[ORM\Entity]
class Item
{
#[ORM\Column(type: 'vector', length: 3)]
private Vector $embedding;
public function setEmbedding(Vector $embedding): void
{
$this->embedding = $embedding;
}
}
Insert a vector
$item = new Item();
$item->setEmbedding(new Vector([1, 2, 3]));
$entityManager->persist($item);
$entityManager->flush();
Get the nearest neighbors to a vector
$neighbors = $entityManager->createQuery('SELECT i FROM Item i ORDER BY l2_distance(i.embedding, ?1)')
->setParameter(1, new Vector([1, 2, 3]))
->setMaxResults(5)
->getResult();
Also supports max_inner_product, cosine_distance, l1_distance, hamming_distance, and jaccard_distance
Enable the extension
pg_query($db, 'CREATE EXTENSION IF NOT EXISTS vector');
Create a table
pg_query($db, 'CREATE TABLE items (embedding vector(3))');
Insert a vector
use Pgvector\Vector;
$embedding = new Vector([1, 2, 3]);
pg_query_params($db, 'INSERT INTO items (embedding) VALUES ($1)', [$embedding]);
Get the nearest neighbors to a vector
$embedding = new Vector([1, 2, 3]);
$result = pg_query_params($db, 'SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5', [$embedding]);
Add an approximate index
pg_query($db, 'CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)');
// or
pg_query($db, 'CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)');
See a full example
Create a vector from an array
$vec = new Vector([1, 2, 3]);
Get an array
$arr = $vec->toArray();
Create a half vector from an array
$vec = new HalfVector([1, 2, 3]);
Get an array
$arr = $vec->toArray();
Create a sparse vector from an indexed array
$vec = new SparseVector([1, 0, 2, 0, 3, 0]);
Or an associative array of non-zero elements
$elements = [0 => 1, 2 => 2, 4 => 3];
$vec = new SparseVector($elements, 6);
Note: Indices start at 0
Get the number of dimensions
$dim = $vec->dimensions();
Get the indices of non-zero elements
$indices = $vec->indices();
Get the values of non-zero elements
$values = $vec->values();
Get an array
$arr = $vec->toArray();
View the changelog
Everyone is encouraged to help improve this project. Here are a few ways you can help:
To get started with development:
git clone https://github.com/pgvector/pgvector-php.git
cd pgvector-php
composer install
createdb pgvector_php_test
composer test
To run an example:
cd examples/loading
composer install
createdb pgvector_example
php example.php
PHP
100.0%