|
15 | 15 | use PHPUnit\Framework\Attributes\CoversClass;
|
16 | 16 | use PHPUnit\Framework\TestCase;
|
17 | 17 | use Symfony\AI\Platform\Vector\Vector;
|
| 18 | +use Symfony\AI\Store\Bridge\Postgres\Distance; |
18 | 19 | use Symfony\AI\Store\Bridge\Postgres\Store;
|
19 | 20 | use Symfony\AI\Store\Document\Metadata;
|
20 | 21 | use Symfony\AI\Store\Document\VectorDocument;
|
@@ -152,6 +153,53 @@ public function testQueryWithoutMinScore()
|
152 | 153 | $this->assertSame(['title' => 'Test Document'], $results[0]->metadata->getArrayCopy());
|
153 | 154 | }
|
154 | 155 |
|
| 156 | + public function testQueryChangedDistanceMethodWithoutMinScore() |
| 157 | + { |
| 158 | + $pdo = $this->createMock(\PDO::class); |
| 159 | + $statement = $this->createMock(\PDOStatement::class); |
| 160 | + |
| 161 | + $store = new Store($pdo, 'embeddings_table', 'embedding', Distance::Cosine); |
| 162 | + |
| 163 | + $expectedSql = 'SELECT id, embedding AS embedding, metadata, (embedding <=> :embedding) AS score |
| 164 | + FROM embeddings_table |
| 165 | +
|
| 166 | + ORDER BY score ASC |
| 167 | + LIMIT 5'; |
| 168 | + |
| 169 | + $pdo->expects($this->once()) |
| 170 | + ->method('prepare') |
| 171 | + ->with($this->callback(function ($sql) use ($expectedSql) { |
| 172 | + return $this->normalizeQuery($sql) === $this->normalizeQuery($expectedSql); |
| 173 | + })) |
| 174 | + ->willReturn($statement); |
| 175 | + |
| 176 | + $uuid = Uuid::v4(); |
| 177 | + |
| 178 | + $statement->expects($this->once()) |
| 179 | + ->method('execute') |
| 180 | + ->with(['embedding' => '[0.1,0.2,0.3]']); |
| 181 | + |
| 182 | + $statement->expects($this->once()) |
| 183 | + ->method('fetchAll') |
| 184 | + ->with(\PDO::FETCH_ASSOC) |
| 185 | + ->willReturn([ |
| 186 | + [ |
| 187 | + 'id' => $uuid->toRfc4122(), |
| 188 | + 'embedding' => '[0.1,0.2,0.3]', |
| 189 | + 'metadata' => json_encode(['title' => 'Test Document']), |
| 190 | + 'score' => 0.95, |
| 191 | + ], |
| 192 | + ]); |
| 193 | + |
| 194 | + $results = $store->query(new Vector([0.1, 0.2, 0.3])); |
| 195 | + |
| 196 | + $this->assertCount(1, $results); |
| 197 | + $this->assertInstanceOf(VectorDocument::class, $results[0]); |
| 198 | + $this->assertEquals($uuid, $results[0]->id); |
| 199 | + $this->assertSame(0.95, $results[0]->score); |
| 200 | + $this->assertSame(['title' => 'Test Document'], $results[0]->metadata->getArrayCopy()); |
| 201 | + } |
| 202 | + |
155 | 203 | public function testQueryWithMinScore()
|
156 | 204 | {
|
157 | 205 | $pdo = $this->createMock(\PDO::class);
|
@@ -189,6 +237,43 @@ public function testQueryWithMinScore()
|
189 | 237 | $this->assertCount(0, $results);
|
190 | 238 | }
|
191 | 239 |
|
| 240 | + public function testQueryWithMinScoreAndDifferentDistance() |
| 241 | + { |
| 242 | + $pdo = $this->createMock(\PDO::class); |
| 243 | + $statement = $this->createMock(\PDOStatement::class); |
| 244 | + |
| 245 | + $store = new Store($pdo, 'embeddings_table', 'embedding', Distance::Cosine); |
| 246 | + |
| 247 | + $expectedSql = 'SELECT id, embedding AS embedding, metadata, (embedding <=> :embedding) AS score |
| 248 | + FROM embeddings_table |
| 249 | + WHERE (embedding <=> :embedding) >= :minScore |
| 250 | + ORDER BY score ASC |
| 251 | + LIMIT 5'; |
| 252 | + |
| 253 | + $pdo->expects($this->once()) |
| 254 | + ->method('prepare') |
| 255 | + ->with($this->callback(function ($sql) use ($expectedSql) { |
| 256 | + return $this->normalizeQuery($sql) === $this->normalizeQuery($expectedSql); |
| 257 | + })) |
| 258 | + ->willReturn($statement); |
| 259 | + |
| 260 | + $statement->expects($this->once()) |
| 261 | + ->method('execute') |
| 262 | + ->with([ |
| 263 | + 'embedding' => '[0.1,0.2,0.3]', |
| 264 | + 'minScore' => 0.8, |
| 265 | + ]); |
| 266 | + |
| 267 | + $statement->expects($this->once()) |
| 268 | + ->method('fetchAll') |
| 269 | + ->with(\PDO::FETCH_ASSOC) |
| 270 | + ->willReturn([]); |
| 271 | + |
| 272 | + $results = $store->query(new Vector([0.1, 0.2, 0.3]), [], 0.8); |
| 273 | + |
| 274 | + $this->assertCount(0, $results); |
| 275 | + } |
| 276 | + |
192 | 277 | public function testQueryWithCustomLimit()
|
193 | 278 | {
|
194 | 279 | $pdo = $this->createMock(\PDO::class);
|
|
0 commit comments