symfony/ai-maria-db-store
MariaDB vector store integration for Symfony AI Store. Requires MariaDB 11.7+ for VECTOR columns, vector indexing, and distance search. Useful for building RAG and similarity search apps backed by MariaDB.
Install Dependencies
composer require symfony/ai-maria-db-store
Ensure your composer.json includes:
"require": {
"php": "^8.2",
"mariadb/server": "^11.7",
"symfony/ai": "^0.8"
}
Configure MariaDB
VECTOR column and index:
CREATE TABLE `embeddings` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`content` TEXT,
`metadata` JSON,
`embedding` VECTOR(1536), -- Adjust dimension as needed
INDEX `idx_embedding` ((embedding))
) ENGINE=InnoDB;
Basic Laravel Integration
Register the store in AppServiceProvider:
use Symfony\AI\MariaDbStore\MariaDbStore;
use Symfony\Component\AI\Store\AiStoreInterface;
public function register()
{
$this->app->singleton(AiStoreInterface::class, function ($app) {
return new MariaDbStore(
$app['db']->connection()->getPdo(),
[
'table' => 'embeddings',
'vector_column' => 'embedding',
'distance' => 'cosine', // or 'euclidean'
]
);
});
}
First Use Case: Storing/Retrieving Vectors
// Inject AiStoreInterface via constructor
public function __construct(private AiStoreInterface $store) {}
// Store a vector
$this->store->save([
'id' => 'doc1',
'content' => 'Sample content',
'metadata' => ['category' => 'tech'],
'embedding' => [0.1, 0.2, ..., 0.0], // Your 1536-dim vector
]);
// Find nearest neighbors
$results = $this->store->findNearest(
[0.5, 0.3, ..., 0.1], // Query vector
5, // Limit
['metadata.category' => 'tech'] // Optional filter
);
save() with an array of embeddings:
$this->store->save([
['id' => 'doc1', 'embedding' => $vec1, 'metadata' => [...]],
['id' => 'doc2', 'embedding' => $vec2, 'metadata' => [...]],
]);
update() for partial updates (if supported by your MariaDB version).remove() with IDs or filters:
$this->store->remove(['id' => ['doc1', 'doc2']]);
// Or with metadata filter
$this->store->remove(['metadata.category' => 'deprecated']);
Combine vector similarity with metadata queries:
$results = $this->store->findNearest(
$queryVector,
10,
[
'metadata.published' => true,
'metadata.language' => 'en',
]
);
Under the hood, this translates to:
SELECT * FROM embeddings
WHERE metadata->>'$.published' = 'true'
AND metadata->>'$.language' = 'en'
ORDER BY embedding <=> ? -- Cosine distance
LIMIT 10;
Configure the distance function in the store options:
$store = new MariaDbStore(..., ['distance' => 'euclidean']);
Supported values: 'cosine' (default), 'euclidean', or 'l2'.
Use findNearest() with offset and limit:
$page1 = $this->store->findNearest($query, 10, [], 0, 10);
$page2 = $this->store->findNearest($query, 10, [], 10, 10);
Query Builder Integration
For complex queries, use raw PDO via Laravel’s DB facade:
$results = DB::select(
'SELECT * FROM embeddings
ORDER BY embedding <=> ?
LIMIT ?',
[$queryVector, 5]
);
Model Binding Attach vectors to Eloquent models:
use Symfony\AI\MariaDbStore\MariaDbStore;
class Document extends Model
{
public function getEmbedding(): array
{
return $this->embedding; // Assuming `embedding` is a serialized vector
}
public function saveToStore(MariaDbStore $store)
{
$store->save([
'id' => $this->id,
'embedding' => $this->getEmbedding(),
'metadata' => $this->metadata,
]);
}
}
Artisan Commands Create a command to manage vectors:
use Illuminate\Console\Command;
use Symfony\Component\AI\Store\AiStoreInterface;
class VectorSyncCommand extends Command
{
protected $signature = 'vectors:sync';
protected $description = 'Sync documents to MariaDB vector store';
public function handle(AiStoreInterface $store)
{
foreach (Document::all() as $doc) {
$store->save($doc->toArrayForStore());
}
}
}
Indexing
Ensure your VECTOR column has an index:
CREATE INDEX idx_embedding ON embeddings ((embedding));
For large datasets, consider IVF (Inverted File Index):
ALTER TABLE embeddings ADD INDEX idx_embedding_ivf ((embedding) USING IVF);
Batch Operations Use transactions for bulk inserts:
DB::transaction(function () use ($store, $vectors) {
$store->save($vectors);
});
Caching Cache frequent queries with Laravel’s cache:
$cacheKey = 'vector_query_' . md5(serialize($queryVector));
$results = Cache::remember($cacheKey, now()->addMinutes(5), function () use ($store, $queryVector) {
return $store->findNearest($queryVector, 10);
});
MariaDB Version Requirements
Unknown column type 'VECTOR' or Function 'vector' doesn't exist.vector engine:
INSTALL PLUGIN vector SONAME 'vector';
Vector Dimension Mismatch
Vector dimension mismatch when inserting/retrieving.all-MiniLM-L6-v2 embeddings). Validate with:
$store->getVectorDimension(); // Check expected dimension
Distance Function Confusion
Unknown function 'distance' or incorrect similarity scores.embedding <=> ? (default in the package).SQRT(SUM(POWER(embedding - ?, 2))).SELECT embedding <=> [1,0,0] FROM embeddings WHERE id = 'doc1';
Filter Syntax Quirks
JSON path not found or Invalid filter.// Correct
['metadata->$.category' => 'tech']
// Or for nested JSON
['metadata->$.user->$.role' => 'admin']
Connection Pooling
$pdo = DB::connection()->getPdo();
$store = new MariaDbStore($pdo, $config);
my.cnf:
[mysqld]
general_log = 1
general_log_file = /var
How can I help you explore Laravel packages today?