pgvector-php

repository·master·Indexed 41 days ago

https://github.com/pgvector/pgvector-php

PHP support for the pgvector extension in PostgreSQL, enabling vector similarity search. Provides integration for Laravel, Symfony, and Doctrine, and supports native PgSql usage. Includes support for vector, halfvec, bit, and sparsevec types, as well as distance functions including L2, InnerProduct, Cosine, L1, Hamming, and Jaccard.

Tokens
4.4K
Snippets
18
Records
18
Agent score
52%

What's inside pgvector-php

  1. Use pgvector-php with Doctrine

    master

    For standalone Doctrine usage, install the package and register the types using PgvectorSetup::registerTypes($entityManager). Ensure the extension is enabled by executing CREATE EXTENSION IF NOT EXISTS vector; on the connection.

    Entity and Querying: Use Pgvector\Vector for the column type and query using distance functions like l2_distance in DQL.

    use Pgvector\​Doctrine\PgvectorSetup;
    use Pgvector\Vector;
    
    // Register types
    PgvectorSetup::registerTypes($entityManager);
    
    // Enable extension
    $entityManager->getConnection()->executeStatement('CREATE EXTENSION IF NOT EXISTS vector');
    
    // Querying
    $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();
  2. Use pgvector-php with Laravel

    master

    After setting up migrations, define your schema and model to support vector operations.

    Migration:

    $table->vector('embedding', 3);

    Model:

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

    Operations:

    • Insert: Assign an array to the property: $item->embedding = [1, 2, 3];
    • Nearest Neighbors (from record): $item->nearestNeighbors('embedding', Distance::L2)->take(5)->get();
    • Nearest Neighbors (from vector): Item::query()->nearestNeighbors('embedding', [1, 2, 3], Distance::L2)->take(5)->get();
    • Distance functions: Supports L2, InnerProduct, Cosine, L1, Hamming, and Jaccard via Pgvector\Laravel\Distance.
    // 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();
    
    // 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');
  3. Setup pgvector-php with Symfony

    master

    Install the package via Composer and register the vector types and distance functions in your Doctrine configuration (config/packages/doctrine.yaml).

    Configuration: Register vector, halfvec, bit, and sparsevec under dbal.types. Register distance functions like l2_distance, cosine_distance, etc., under orm.dql.numeric_functions.

    Extension Setup: Generate a migration and add CREATE EXTENSION vector; to the up() method, then run the migration.

    Entity Usage: Use Pgvector\Vector as the type for your column.

    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
  4. Setup pgvector-php with Laravel

    master

    To use pgvector in Laravel, install the package via Composer, publish the migrations to enable the extension, and then run the migrations. You can use vector, halfvec, bit, and sparsevec types in your migrations. Use the HasNeighbors trait and Pgvector\​Laravel\​Vector class for model casting.

    composer require pgvector/pgvector
    
    php artisan vendor:publish --tag="pgvector-migrations"
    php artisan migrate
  5. Use pgvector-php with Symfony

    master

    After configuring Doctrine, use the Pgvector\Vector class in your entities.

    Insert:

    $item = new Item();
    $item->setEmbedding(new Vector([1, 2, 3]));
    $entityManager->persist($item);
    $entityManager->flush();

    Querying: Use DQL with the registered distance functions:

    $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();
    use Pgvector\Vector;
    
    $item = new Item();
    $item->setEmbedding(new Vector([1, 2, 3]));
    $entityManager->persist($item);
    $entityManager->flush();
    
    $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();
  6. Use pgvector-php with PgSql (Native)

    master

    For direct use with PHP's pgsql extension, ensure the vector extension is enabled. You can use Pgvector\Vector objects directly with pg_query_params to insert or query vectors.

    Example Operations:

    • Insert: pg_query_params($db, 'INSERT INTO items (embedding) VALUES ($1)', [$embedding]);
    • Search: pg_query_params($db, 'SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5', [$embedding]); (Note: <-> is the L2 distance operator).
    • Indexing: Use CREATE INDEX ... USING hnsw or ivfflat with appropriate operator classes like vector_l2_ops, vector_ip_ops, or vector_cosine_ops.
    use Pgvector\Vector;
    
    // Enable extension
    pg_query($db, 'CREATE EXTENSION IF NOT EXISTS vector');
    
    // Create table
    pg_query($db, 'CREATE TABLE items (embedding vector(3))');
    
    // Insert
    $embedding = new Vector([1, 2, 3]);
    pg_query_params($db, 'INSERT INTO items (embedding) VALUES ($1)', [$embedding]);
    
    // Search
    $embedding = new Vector([1, 2, 3]);
    $result = pg_query_params($db, 'SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5', [$embedding]);
    
    // Indexing
    pg_query($db, 'CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)');
  7. Integrate pgvector with Laravel

    master

    The PgvectorServiceProvider automatically handles the registration of migrations and schema extensions for Laravel applications.

    To ensure the migrations are part of your application's migration directory (allowing you to publish and modify them if necessary), you can use the pgvector-migrations tag with the vendor:publish command.

    Additionally, the provider automatically registers the Schema facade extensions required to work with vector types in your Laravel migrations.

    php artisan vendor:publish --tag=pgvector-migrations
  8. Reference: Vector types

    master

    The library provides classes to handle different pgvector types.

    Vectors

    Create a standard vector from an array.

    $vec = new Vector([1, 2, 3]);
    $arr = $vec->toArray();

    Half Vectors

    Create a half vector from an array.

    $vec = new HalfVector([1, 2, 3]);
    $arr = $vec->toArray();

    Sparse Vectors

    Create a sparse vector using either an indexed array or an associative array of non-zero elements. Indices start at 0.

    // From indexed array
    $vec = new SparseVector([1, 0, 2, 0, 3, 0]);
    
    // From associative array (non-zero elements)
    $elements = [0 => 1, 2 => 2, 4 => 3];
    $vec = new SparseVector($elements, 6);
    
    // Methods
    $dim = $vec->dimensions();     // Number of dimensions
    $indices = $vec->indices();     // Indices of non-zero elements
    $values = $vec->values();       // Values of non-zero elements
    $arr = $vec->toArray();        // Get array representation
    // Vector
    $vec = new Vector([1, 2, 3]);
    $arr = $vec->toArray();
    
    // HalfVector
    $vec = new HalfVector([1, 2, 3]);
    $arr = $vec->toArray();
    
    // SparseVector
    $vec = new SparseVector([1, 0, 2, 0, 3, 0]);
    $elements = [0 => 1, 2 => 2, 4 => 3];
    $vec = new SparseVector($elements, 6);
    $dim = $vec->dimensions();
    $indices = $vec->indices();
    $values = $vec->values();
    $arr = $vec->toArray();
  9. Convert a Vector to an array or string

    master

    Once a Pgvector\Vector instance is created, you can retrieve its underlying data using toArray() or convert it to a JSON string representation using __toString() (e.g., when passing it to a database driver).

    use Pgvector\Vector;
    
    $vector = new Vector([1.0, 2.0, 3.0]);
    
    // Get the raw array
    $array = $vector->toArray(); // [1.0, 2.0, 3.0]
    
    // Get the JSON string representation
    $string = (string) $vector; // "[1.0, 2.0, 3.0]"
  10. Use HalfVectorType in Doctrine

    master

    The HalfVectorType allows you to map PostgreSQL halfvec columns to Pgvector\HalfVector objects within a Doctrine ORM/DBAL entity.

    When defining your schema or mapping, use the type name halfvec. If you specify a length in your field declaration, it will be rendered as halfvec(n) in SQL; otherwise, it defaults to halfvec.

    To use this type, you must register it with Doctrine's Type system.

    // Example mapping in a Doctrine Entity
    #[ORM// Column(type: 'halfvec', options: ['length' => 128])]
    private ?HalfVector $embedding = null;
  11. Create a Vector instance

    master

    The Pgvector\Vector class represents a vector for use with PostgreSQL. You can instantiate it using a numeric list (array) or a JSON string representing a list of numbers.

    If you provide a string, the class attempts to decode it as JSON. If the string is not valid JSON or does not represent a list, an InvalidArgumentException is thrown. If you provide an array, it must be a list (sequential integer keys).

    use Pgvector\Vector;
    
    // From an array
    $vector = new Vector([1.0, 2.0, 3.0]);
    
    // From a JSON string
    $vector = new Vector('[1.0, 2.0, 3.0]');
  12. Instantiate a HalfVector

    master

    The HalfVector class represents a half-precision vector. You can instantiate it using a list of values (array) or a JSON string representation of that list. If a string is provided, it must be a valid JSON array. If an array is provided, it must be a list (sequential integer keys).

    use Pgvector\HalfVector;
    
    // From an array
    $vector = new HalfVector([0.1, 0.2, 0.3]);
    
    // From a JSON string
    $vector = new HalfVector('[0.1, 0.2, 0.3]');