Looking to hire Laravel developers? Try LaraJobs

laravel-vector-schema maintained by illuma-law

Description
Portable Eloquent casts and Blueprint schema macros for pgvector and sqlite-vec.
Author
Last update
2026/04/20 20:50 (dev-main)
License
Downloads
2

Comments
comments powered by Disqus

Laravel Vector Schema

Tests Packagist License Latest Stable Version

Portable vector columns and macros for Laravel

This package provides Eloquent casts and Blueprint schema macros for vector search, supporting multiple databases with a single API.

Database Support Matrix

Database Support Level Requirements Distance Function
PostgreSQL Native pgvector extension <=> (Cosine)
MySQL (9.0+) Native HeatWave or Enterprise Edition VECTOR_DISTANCE
MariaDB (11.7+) Native None VEC_DISTANCE_COSINE
SQL Server Native Azure SQL (Preview) VECTOR_DISTANCE
SingleStore Native None DOT_PRODUCT
SQLite Native sqlite-vec extension vec_distance_cosine

Note: MySQL Community Edition (GPL) currently restricts the VECTOR_DISTANCE function to HeatWave/Enterprise users.

Installation

Require this package with composer using the following command:

composer require illuma-law/laravel-vector-schema

Usage

TL;DR

Create a vector column in your migration:

$table->vectorColumn('embedding', 768)->nullable();
$table->hnswIndex('embedding');

Add the cast to your model:

protected $casts = ['embedding' => VectorArray::class];

Search for similar vectors:

$results = Document::query()
    ->whereHybridVectorSimilarTo('embedding', $queryVector, minSimilarity: 0.7)
    ->get();

Schema Migrations

This package introduces macros to Laravel's Blueprint class, allowing you to define vector columns that automatically adapt to your database driver.

Use the vectorColumn macro to define portable vector columns. On PostgreSQL, MySQL, MariaDB, SQL Server, and SingleStore, this creates a native vector column. On SQLite, it safely falls back to a BLOB column compatible with sqlite-vec.

Use hnswIndex for high-performance approximate nearest neighbor (ANN) similarity search on PostgreSQL (this is gracefully ignored on other drivers).

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use IllumaLaw\VectorSchema\VectorSchema;

return new class extends Migration {
    public function up(): void
    {
        // Automatically ensures pgvector exists on PostgreSQL
        VectorSchema::ensureExtension();

        Schema::create('documents', function (Blueprint $table) {
            $table->id();
            $table->text('content');
            
            // Defines 'vector' type natively, or 'BLOB' on sqlite
            $table->vectorColumn('embedding', 768)->nullable();
            
            $table->timestamps();
        });

        // Creates an HNSW index on pgsql (ignored on others)
        Schema::table('documents', function (Blueprint $table) {
            $table->hnswIndex('embedding');
        });
    }

    public function down(): void
    {
        Schema::table('documents', function (Blueprint $table) {
            $table->dropHnswIndex('embedding');
        });
        Schema::dropIfExists('documents');
    }
};

Eloquent Casts

Add the VectorArray cast to your model. This handles the serialization and deserialization of PHP arrays to the specific formats required by the database (e.g. vector string representation or SQLite's binary BLOB).

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use IllumaLaw\VectorSchema\Casts\VectorArray;

class Document extends Model
{
    protected $casts = [
        'embedding' => VectorArray::class,
    ];
}

Vector Querying

The package provides several Query and Eloquent Builder macros to perform vector mathematics and similarity searches portably.

whereHybridVectorSimilarTo

Filter results to only include those that meet a minimum cosine similarity threshold. You can also automatically order the results by similarity (closest first).

$queryEmbedding = [...]; // Array of 768 floats

$results = Document::query()
    ->whereHybridVectorSimilarTo(
        column: 'embedding', 
        vector: $queryEmbedding, 
        minSimilarity: 0.7, 
        order: true
    )
    ->get();

selectHybridVectorDistance

Select the raw cosine distance between a stored vector and your query vector into a dynamically named alias. Distance is the inverse of similarity (where 0.0 is an exact match).

$results = Document::query()
    ->select('id', 'content')
    ->selectHybridVectorDistance('embedding', $queryEmbedding, as: 'distance')
    ->orderBy('distance')
    ->get();

echo $results->first()->distance;

whereHybridVectorDistanceLessThan

For advanced use cases, directly filter by the raw distance.

$results = Document::query()
    ->whereHybridVectorDistanceLessThan('embedding', $queryEmbedding, maxDistance: 0.3)
    ->get();

orderByHybridVectorDistance

If you only need to order results by distance without filtering or selecting the distance value:

$results = Document::query()
    ->orderByHybridVectorDistance('embedding', $queryEmbedding, 'asc')
    ->get();

Testing

The package includes a comprehensive test suite using Pest.

composer test

For SQLite testing, ensure sqlite-vec is available in your environment. The CI workflow handles this automatically by downloading the pre-compiled vec0.so extension for Linux.

Credits

License

The MIT License (MIT). Please see License File for more information.