Skip to content

Repository files navigation

pgvector-php

pgvector support for PHP

Supports Laravel, Symfony, Doctrine, and PgSql

Build Status

Getting Started

Follow the instructions for your database library:

Or check out some examples:

Laravel

Note: 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

usePgvector\Laravel\Vector;
class Item extends Model
{
use HasNeighbors;
protected$casts = ['embedding' => Vector::class];
}

Insert a vector

$item = newItem();
$item->embedding = [1, 2, 3];
$item->save();

Get the nearest neighbors to a record

usePgvector\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

publicfunctionup()
{
DB::statement('CREATE INDEX my_index ON items USING hnsw (embedding vector_l2_ops)');
// orDB::statement('CREATE INDEX my_index ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)');
}
publicfunctiondown()
{
DB::statement('DROP INDEX my_index');
}

Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance

Symfony

Install the package

composer require pgvector/pgvector

Register the types and distance functions in config/packages/doctrine.yaml

doctrine:
dbal:
types:
vector: Pgvector\Doctrine\VectorTypehalfvec: Pgvector\Doctrine\HalfVectorTypebit: Pgvector\Doctrine\BitTypesparsevec: Pgvector\Doctrine\SparseVectorTypeorm:
dql:
numeric_functions:
l2_distance: Pgvector\Doctrine\L2Distancemax_inner_product: Pgvector\Doctrine\MaxInnerProductcosine_distance: Pgvector\Doctrine\CosineDistancel1_distance: Pgvector\Doctrine\L1Distancehamming_distance: Pgvector\Doctrine\HammingDistancejaccard_distance: Pgvector\Doctrine\JaccardDistance

Create a migration to enable the extension

php bin/console doctrine:migrations:generate

And update it

publicfunctionup(Schema$schema): void
{
$this->addSql('CREATE EXTENSION vector');
}
publicfunctiondown(Schema$schema): void
{
$this->addSql('DROP EXTENSION vector');
}

Migrate

php bin/console doctrine:migrations:migrate

Update your entity

usePgvector\Vector;
#[ORM\Entity(repositoryClass: ItemRepository::class)]
class Item
{
#[ORM\Column(type: 'vector', length: 3)]
private ?Vector$embedding = null;
publicfunctiongetEmbedding(): ?Vector
{
return$this->embedding;
}
publicfunctionsetEmbedding(Vector$embedding): static
{
$this->embedding = $embedding;
return$this;
}
}

Migrate

php bin/console make:migration
php bin/console doctrine:migrations:migrate

Insert a vector

$item = newItem();
$item->setEmbedding(newVector([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, newVector([1, 2, 3]))
->setMaxResults(5)
->getResult();

Also supports max_inner_product, cosine_distance, l1_distance, hamming_distance, and jaccard_distance

Doctrine

Install the package

composer require pgvector/pgvector

Register the types and distance functions

usePgvector\Doctrine\PgvectorSetup;
PgvectorSetup::registerTypes($entityManager);

Enable the extension

$entityManager->getConnection()->executeStatement('CREATE EXTENSION IF NOT EXISTS vector');

Update your entity

usePgvector\Vector;
#[ORM\Entity]
class Item
{
#[ORM\Column(type: 'vector', length: 3)]
privateVector$embedding;
publicfunctionsetEmbedding(Vector$embedding): void
{
$this->embedding = $embedding;
}
}

Insert a vector

$item = newItem();
$item->setEmbedding(newVector([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, newVector([1, 2, 3]))
->setMaxResults(5)
->getResult();

Also supports max_inner_product, cosine_distance, l1_distance, hamming_distance, and jaccard_distance

PgSql

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

usePgvector\Vector;
$embedding = newVector([1, 2, 3]);
pg_query_params($db, 'INSERT INTO items (embedding) VALUES ($1)', [$embedding]);

Get the nearest neighbors to a vector

$embedding = newVector([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)');
// orpg_query($db, 'CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)');

See a full example

Reference

Vectors

Create a vector from an array

$vec = newVector([1, 2, 3]);

Get an array

$arr = $vec->toArray();

Half Vectors

Create a half vector from an array

$vec = newHalfVector([1, 2, 3]);

Get an array

$arr = $vec->toArray();

Sparse Vectors

Create a sparse vector from an indexed array

$vec = newSparseVector([1, 0, 2, 0, 3, 0]);

Or an associative array of non-zero elements

$elements = [0 => 1, 2 => 2, 4 => 3];
$vec = newSparseVector($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();

History

View the changelog

Contributing

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

About

pgvector support for PHP

Resources

Security policy

Stars

199 stars

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages