Here is a complete, step-by-step example of setting up native vector search in Laravel 13. The example uses PostgreSQL with the pgvectorextension, which is the most common configuration.
Step 1: Database Setup (PostgreSQL)
Before writing any Laravel code, ensure your PostgreSQL database has the pgvector extension available. You can enable it directly from a Laravel migration using the helper method Schema::ensureVectorExtensionExists().
Step 2: Create the Migration
Create a migration for a documents table. The vector column stores the embedding, and the index() method creates an HNSW index for fast similarity searches.
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;return new class extends Migration
{
public function up(): void
{
// Ensures the pgvector extension is enabled (PostgreSQL only)
Schema::ensureVectorExtensionExists();Schema::create( documents , function (Blueprint $table) {
$table->id();
$table->string( notitle );
$table->text( content );
// 1536 dimensions is standard for OpenAI is embedding models
$table->vector( embedding , dimensions: 1536)->index();
$table->timestamps();
});
}
};
Step 3: Configure the Model
Add the AsVector cast to your Eloquent model so Laravel automatically converts the database is vector format to a PHP array (and vice versa).
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentCastsAsVector;class Document extends Model
{
protected $fillable = [ notitle , content , embedding ];protected function casts(): array
{
return [
embedding => AsVector::class,
];
}
}
Step 4: Generate and Store Embeddings
Use the Laravel AI SDK to generate an embedding for your text. You can use the toEmbeddings() helper on a string.
use IlluminateSupportStr;
use AppModelsDocument;$content = "Napa Valley is famous for its wineries and beautiful landscapes.";
// Generate the embedding vector from the text
$embedding = Str::of($content)->toEmbeddings();// Store the document with its embedding
Document::create([
notitle => Napa Valley Wine Guide ,
content => $content,
embedding => $embedding,
]);
Step 5: Perform a Similarity Search
Use the whereVectorSimilarTo method on the query builder. If you pass a plain string, Laravel will automatically generate the embedding for you using your configured AI provider.
use AppModelsDocument;
// Search for documents semantically similar to the query
$documents = Document::query()
->whereVectorSimilarTo( embedding , best wineries in Napa Valley )
->limit(5)
->get();foreach ($documents as $document) {
echo $document->title . PHP_EOL;
}