pgvector support for PHP
Supports Laravel, Doctrine, and PgSql
Follow the instructions for your database library:
Or check out some examples:
- Embeddings with OpenAI
- Binary embeddings with Cohere
- Hybrid search with Ollama (Reciprocal Rank Fusion)
- Sparse search with Text Embeddings Inference
- Morgan fingerprints with RDKit
- Recommendations with Disco
- Horizontal scaling with Citus
- Bulk loading with
COPY
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
type 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
use Pgvector\Doctrine\PgvectorSetup;
PgvectorSetup::registerTypes($entityManager);
Enable the extension
$entityManager->getConnection()->executeStatement('CREATE EXTENSION IF NOT EXISTS vector');
Update your model
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();
The package name was changed from ankane/pgvector
to pgvector/pgvector
. Update it in composer.json
to remove the message.
View the changelog
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features
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