Skip to content

Commit 806d6be

Browse files
committed
bug #856 [Store] Fix CacheStore and InMemoryStore to return similarity scores (camilleislasse)
This PR was squashed before being merged into the main branch. Discussion ---------- [Store] Fix CacheStore and InMemoryStore to return similarity scores | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | Docs? | no | Issues | n/a | License | MIT ## Description The `DistanceCalculator` was calculating distances but not returning them in the `VectorDocument` results. This meant queries to `CacheStore` and `InMemoryStore` returned documents without score information, making it impossible to determine result relevance. ## Changes This fix creates new `VectorDocument` instances with the calculated distance as the `score` property, matching the pattern used by other stores (Redis, MariaDb, Postgres). Commits ------- 65e85c3 [Store] Fix CacheStore and InMemoryStore to return similarity scores
2 parents fbb2d62 + 65e85c3 commit 806d6be

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

src/store/src/Bridge/Local/DistanceCalculator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function calculate(array $documents, Vector $vector, ?int $maxItems = nul
5858
}
5959

6060
return array_map(
61-
static fn (array $embedding): VectorDocument => $embedding['document'],
61+
static fn (array $embedding): VectorDocument => $embedding['document']->withScore($embedding['distance']),
6262
$currentEmbeddings,
6363
);
6464
}

src/store/src/Document/VectorDocument.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,17 @@ public function __construct(
2626
public readonly ?float $score = null,
2727
) {
2828
}
29+
30+
/**
31+
* Returns a new instance with the given score.
32+
*/
33+
public function withScore(float $score): self
34+
{
35+
return new self(
36+
id: $this->id,
37+
vector: $this->vector,
38+
metadata: $this->metadata,
39+
score: $score,
40+
);
41+
}
2942
}

src/store/tests/Bridge/Local/DistanceCalculatorTest.php

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,12 @@ public function testAngularDistanceCalculation()
158158
$result = $calculator->calculate([$orthogonalDoc, $parallelDoc], $queryVector);
159159

160160
// Parallel vector should be first (smaller angular distance)
161-
$this->assertSame($parallelDoc, $result[0]);
162-
$this->assertSame($orthogonalDoc, $result[1]);
161+
$this->assertEquals($parallelDoc->id, $result[0]->id);
162+
$this->assertEquals($parallelDoc->vector, $result[0]->vector);
163+
$this->assertNotNull($result[0]->score);
164+
$this->assertEquals($orthogonalDoc->id, $result[1]->id);
165+
$this->assertEquals($orthogonalDoc->vector, $result[1]->vector);
166+
$this->assertNotNull($result[1]->score);
163167
}
164168

165169
#[TestDox('Calculates Chebyshev distance using maximum absolute difference')]
@@ -176,9 +180,12 @@ public function testChebyshevDistanceCalculation()
176180
$result = $calculator->calculate([$doc1, $doc2, $doc3], $queryVector);
177181

178182
// doc1 should be first (distance 0), doc2 second (max diff 0.5), doc3 last (max diff 3.0)
179-
$this->assertSame($doc1, $result[0]);
180-
$this->assertSame($doc2, $result[1]);
181-
$this->assertSame($doc3, $result[2]);
183+
$this->assertEquals($doc1->id, $result[0]->id);
184+
$this->assertNotNull($result[0]->score);
185+
$this->assertEquals($doc2->id, $result[1]->id);
186+
$this->assertNotNull($result[1]->score);
187+
$this->assertEquals($doc3->id, $result[2]->id);
188+
$this->assertNotNull($result[2]->score);
182189
}
183190

184191
#[TestDox('Returns empty array when no documents are provided')]
@@ -201,7 +208,9 @@ public function testSingleDocument()
201208
$result = $calculator->calculate([$doc], new Vector([0.0, 0.0, 0.0]));
202209

203210
$this->assertCount(1, $result);
204-
$this->assertSame($doc, $result[0]);
211+
$this->assertEquals($doc->id, $result[0]->id);
212+
$this->assertEquals($doc->vector, $result[0]->vector);
213+
$this->assertNotNull($result[0]->score);
205214
}
206215

207216
#[TestDox('Handles high-dimensional vectors correctly')]
@@ -222,8 +231,10 @@ public function testHighDimensionalVectors()
222231
$result = $calculator->calculate([$doc1, $doc2], $queryVector);
223232

224233
// doc1 should be closer to query vector (0.15 is closer to 0.1 than to 0.2)
225-
$this->assertSame($doc1, $result[0]);
226-
$this->assertSame($doc2, $result[1]);
234+
$this->assertEquals($doc1->id, $result[0]->id);
235+
$this->assertNotNull($result[0]->score);
236+
$this->assertEquals($doc2->id, $result[1]->id);
237+
$this->assertNotNull($result[1]->score);
227238
}
228239

229240
#[TestDox('Handles negative vector components correctly')]
@@ -240,7 +251,8 @@ public function testNegativeVectorComponents()
240251
$result = $calculator->calculate([$doc1, $doc2, $doc3], $queryVector);
241252

242253
// doc1 should be first (identical to query)
243-
$this->assertSame($doc1, $result[0]);
254+
$this->assertEquals($doc1->id, $result[0]->id);
255+
$this->assertNotNull($result[0]->score);
244256
}
245257

246258
#[TestDox('Returns all documents when maxItems exceeds document count')]
@@ -271,7 +283,8 @@ public function testManhattanDistanceWithMixedSigns()
271283
$result = $calculator->calculate([$doc1, $doc2, $doc3], $queryVector);
272284

273285
// doc3 has smallest Manhattan distance (2.0), then doc1 and doc2 (both 4.0)
274-
$this->assertSame($doc3, $result[0]);
286+
$this->assertEquals($doc3->id, $result[0]->id);
287+
$this->assertNotNull($result[0]->score);
275288
}
276289

277290
#[TestDox('Uses cosine distance as default strategy')]

0 commit comments

Comments
 (0)