Case 1. Semantic search on vectors manually (pure PHP)
Ranking documents by cosine similarity of vectors
Below is a pure PHP semantic search example: both documents and query already have vector representations, then we compute cosine similarity, sort by score, and return the top-N most relevant documents.
Example of code:
<?php
$documents = [
[
'title' => 'Optimizing bulk email campaigns',
'embedding' => [0.12, 0.88, 0.33, 0.55, 0.71],
],
[
'title' => 'Configuring queues in Laravel',
'embedding' => [0.18, 0.79, 0.41, 0.60, 0.66],
],
[
'title' => 'RabbitMQ and background jobs',
'embedding' => [0.14, 0.81, 0.39, 0.58, 0.69],
],
[
'title' => 'Scaling PHP workers',
'embedding' => [0.11, 0.81, 0.36, 0.63, 0.72],
],
[
'title' => 'Redis queues in production',
'embedding' => [0.15, 0.18, 0.31, 0.52, 0.62],
],
[
'title' => 'Monitoring email delivery',
'embedding' => [0.09, 0.91, 0.28, 0.57, 0.74],
],
[
'title' => 'Kubernetes autoscaling',
'embedding' => [0.32, 0.61, 0.70, 0.40, 0.51],
],
[
'title' => 'How to make coffee at home',
'embedding' => [0.91, 0.04, 0.15, 0.08, 0.02],
],
[
'title' => 'History of Ancient Rome',
'embedding' => [0.84, 0.12, 0.10, 0.21, 0.07],
],
[
'title' => 'Traveling across Iceland',
'embedding' => [0.73, 0.18, 0.22, 0.19, 0.11],
],
];
function cosineSimilarity(array $a, array $b): float {
$dotProduct = 0.0;
$normA = 0.0;
$normB = 0.0;
foreach ($a as $i => $value) {
$dotProduct += $value * $b[$i];
$normA += $value ** 2;
$normB += $b[$i] ** 2;
}
if ($normA == 0.0 || $normB == 0.0) {
return 0.0;
}
return $dotProduct / (sqrt($normA) * sqrt($normB));
}