Skip to content

Commit d8a3938

Browse files
committed
feature #1081 [Store] Use codewithkyrian/chromadb-php v1.0 and drop 0.x (OskarStark)
This PR was merged into the main branch. Discussion ---------- [Store] Use `codewithkyrian/chromadb-php` v1.0 and drop 0.x | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | Docs? | no | Issues | Replaces #1076 | License | MIT - Update codewithkyrian/chromadb-php requirement from ^0.2.1|^0.3|^0.4 to ^1.0 - Update namespaces for v1.0 BC breaks: - QueryItemsResponse moved to Codewithkyrian\ChromaDB\Responses - CollectionResource replaced with Collection in Codewithkyrian\ChromaDB\Models - Remove queryImages parameter from query() call (removed in v1.0) - Add queryTexts option to query() method for text-based searches Commits ------- 537169f [Store] Update ChromaDB bridge to support v1.0
2 parents fdd5b43 + 537169f commit d8a3938

File tree

4 files changed

+64
-23
lines changed

4 files changed

+64
-23
lines changed

src/store/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"symfony/uid": "^7.3|^8.0"
4949
},
5050
"require-dev": {
51-
"codewithkyrian/chromadb-php": "^0.2.1|^0.3|^0.4",
51+
"codewithkyrian/chromadb-php": "^1.0",
5252
"doctrine/dbal": "^3.3|^4.0",
5353
"mongodb/mongodb": "^1.21|^2.0",
5454
"phpstan/phpstan": "^2.0",

src/store/src/Bridge/ChromaDb/Store.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ public function add(VectorDocument ...$documents): void
4545
}
4646

4747
$collection = $this->client->getOrCreateCollection($this->collectionName);
48+
49+
// @phpstan-ignore argument.type (chromadb-php library has incorrect PHPDoc type for $metadatas parameter)
4850
$collection->add($ids, $vectors, $metadata, $originalDocuments);
4951
}
5052

5153
/**
52-
* @param array{where?: array<string, string>, whereDocument?: array<string, mixed>, include?: array<string>} $options
54+
* @param array{where?: array<string, string>, whereDocument?: array<string, mixed>, include?: array<string>, queryTexts?: array<string>} $options
5355
*/
5456
public function query(Vector $vector, array $options = []): iterable
5557
{
@@ -65,6 +67,7 @@ public function query(Vector $vector, array $options = []): iterable
6567
$collection = $this->client->getOrCreateCollection($this->collectionName);
6668
$queryResponse = $collection->query(
6769
queryEmbeddings: [$vector->getData()],
70+
queryTexts: $options['queryTexts'] ?? null,
6871
nResults: 4,
6972
where: $options['where'] ?? null,
7073
whereDocument: $options['whereDocument'] ?? null,

src/store/src/Bridge/ChromaDb/Tests/StoreTest.php

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
namespace Symfony\AI\Store\Bridge\ChromaDb\Tests;
1313

1414
use Codewithkyrian\ChromaDB\Client;
15-
use Codewithkyrian\ChromaDB\Generated\Responses\QueryItemsResponse;
16-
use Codewithkyrian\ChromaDB\Resources\CollectionResource;
15+
use Codewithkyrian\ChromaDB\Models\Collection;
16+
use Codewithkyrian\ChromaDB\Responses\QueryItemsResponse;
1717
use PHPUnit\Framework\Attributes\DataProvider;
1818
use PHPUnit\Framework\TestCase;
1919
use Symfony\AI\Platform\Vector\Vector;
@@ -39,7 +39,7 @@ public function testAddDocumentsSuccessfully(
3939
array $expectedMetadata,
4040
array $expectedOriginalDocuments,
4141
): void {
42-
$collection = $this->createMock(CollectionResource::class);
42+
$collection = $this->createMock(Collection::class);
4343
$client = $this->createMock(Client::class);
4444

4545
$client->expects($this->once())
@@ -146,7 +146,7 @@ public function testQueryWithoutFilters()
146146
distances: null
147147
);
148148

149-
$collection = $this->createMock(CollectionResource::class);
149+
$collection = $this->createMock(Collection::class);
150150
$client = $this->createMock(Client::class);
151151

152152
$client->expects($this->once())
@@ -159,7 +159,6 @@ public function testQueryWithoutFilters()
159159
->with(
160160
[[0.15, 0.25, 0.35]], // queryEmbeddings
161161
null, // queryTexts
162-
null, // queryImages
163162
4, // nResults
164163
null, // where
165164
null, // whereDocument
@@ -191,7 +190,7 @@ public function testQueryWithWhereFilter()
191190
distances: null
192191
);
193192

194-
$collection = $this->createMock(CollectionResource::class);
193+
$collection = $this->createMock(Collection::class);
195194
$client = $this->createMock(Client::class);
196195

197196
$client->expects($this->once())
@@ -204,7 +203,6 @@ public function testQueryWithWhereFilter()
204203
->with(
205204
[[0.15, 0.25, 0.35]], // queryEmbeddings
206205
null, // queryTexts
207-
null, // queryImages
208206
4, // nResults
209207
['category' => 'technology'], // where
210208
null, // whereDocument
@@ -235,7 +233,7 @@ public function testQueryWithWhereDocumentFilter()
235233
distances: null
236234
);
237235

238-
$collection = $this->createMock(CollectionResource::class);
236+
$collection = $this->createMock(Collection::class);
239237
$client = $this->createMock(Client::class);
240238

241239
$client->expects($this->once())
@@ -248,7 +246,6 @@ public function testQueryWithWhereDocumentFilter()
248246
->with(
249247
[[0.15, 0.25, 0.35]], // queryEmbeddings
250248
null, // queryTexts
251-
null, // queryImages
252249
4, // nResults
253250
null, // where
254251
['$contains' => 'machine learning'], // whereDocument
@@ -280,7 +277,7 @@ public function testQueryWithBothFilters()
280277
distances: null
281278
);
282279

283-
$collection = $this->createMock(CollectionResource::class);
280+
$collection = $this->createMock(Collection::class);
284281
$client = $this->createMock(Client::class);
285282

286283
$client->expects($this->once())
@@ -293,7 +290,6 @@ public function testQueryWithBothFilters()
293290
->with(
294291
[[0.15, 0.25, 0.35]], // queryEmbeddings
295292
null, // queryTexts
296-
null, // queryImages
297293
4, // nResults
298294
['category' => 'AI', 'status' => 'published'], // where
299295
['$contains' => 'neural networks'], // whereDocument
@@ -327,7 +323,7 @@ public function testQueryWithEmptyResults()
327323
distances: null
328324
);
329325

330-
$collection = $this->createMock(CollectionResource::class);
326+
$collection = $this->createMock(Collection::class);
331327
$client = $this->createMock(Client::class);
332328

333329
$client->expects($this->once())
@@ -340,7 +336,6 @@ public function testQueryWithEmptyResults()
340336
->with(
341337
[[0.15, 0.25, 0.35]], // queryEmbeddings
342338
null, // queryTexts
343-
null, // queryImages
344339
4, // nResults
345340
['category' => 'nonexistent'], // where
346341
null, // whereDocument
@@ -367,7 +362,7 @@ public function testQueryReturnsDistancesAsScore()
367362
distances: [[0.123, 0.456]]
368363
);
369364

370-
$collection = $this->createMock(CollectionResource::class);
365+
$collection = $this->createMock(Collection::class);
371366
$client = $this->createMock(Client::class);
372367

373368
$client->expects($this->once())
@@ -400,7 +395,7 @@ public function testQueryReturnsNullScoreWhenDistancesNotAvailable()
400395
distances: null
401396
);
402397

403-
$collection = $this->createMock(CollectionResource::class);
398+
$collection = $this->createMock(Collection::class);
404399
$client = $this->createMock(Client::class);
405400

406401
$client->expects($this->once())
@@ -442,7 +437,7 @@ public function testQueryWithVariousFilterCombinations(
442437
distances: null
443438
);
444439

445-
$collection = $this->createMock(CollectionResource::class);
440+
$collection = $this->createMock(Collection::class);
446441
$client = $this->createMock(Client::class);
447442

448443
$client->expects($this->once())
@@ -455,7 +450,6 @@ public function testQueryWithVariousFilterCombinations(
455450
->with(
456451
[[0.1, 0.2, 0.3]], // queryEmbeddings
457452
null, // queryTexts
458-
null, // queryImages
459453
4, // nResults
460454
$expectedWhere, // where
461455
$expectedWhereDocument,// whereDocument
@@ -482,7 +476,7 @@ public function testQueryReturnsMetadatasEmbeddingsDistanceWithoutInclude()
482476
distances: null
483477
);
484478

485-
$collection = $this->createMock(CollectionResource::class);
479+
$collection = $this->createMock(Collection::class);
486480
$client = $this->createMock(Client::class);
487481

488482
$client->expects($this->once())
@@ -516,7 +510,7 @@ public function testQueryReturnsMetadatasEmbeddingsDistanceWithOnlyDocuments()
516510
distances: null
517511
);
518512

519-
$collection = $this->createMock(CollectionResource::class);
513+
$collection = $this->createMock(Collection::class);
520514
$client = $this->createMock(Client::class);
521515

522516
$client->expects($this->once())
@@ -550,7 +544,7 @@ public function testQueryReturnsMetadatasEmbeddingsDistanceWithAll()
550544
distances: null
551545
);
552546

553-
$collection = $this->createMock(CollectionResource::class);
547+
$collection = $this->createMock(Collection::class);
554548
$client = $this->createMock(Client::class);
555549

556550
$client->expects($this->once())
@@ -641,4 +635,48 @@ public static function queryFilterProvider(): \Iterator
641635
],
642636
];
643637
}
638+
639+
public function testQueryWithQueryTexts()
640+
{
641+
$queryVector = new Vector([0.15, 0.25, 0.35]);
642+
$queryTexts = ['search for this text'];
643+
644+
$queryResponse = new QueryItemsResponse(
645+
ids: [['01234567-89ab-cdef-0123-456789abcdef']],
646+
embeddings: [[[0.1, 0.2, 0.3]]],
647+
metadatas: [[['title' => 'Doc 1']]],
648+
documents: null,
649+
data: null,
650+
uris: null,
651+
distances: [[0.123]]
652+
);
653+
654+
$collection = $this->createMock(Collection::class);
655+
$client = $this->createMock(Client::class);
656+
657+
$client->expects($this->once())
658+
->method('getOrCreateCollection')
659+
->with('test-collection')
660+
->willReturn($collection);
661+
662+
$collection->expects($this->once())
663+
->method('query')
664+
->with(
665+
[[0.15, 0.25, 0.35]], // queryEmbeddings
666+
['search for this text'], // queryTexts
667+
4, // nResults
668+
null, // where
669+
null, // whereDocument
670+
null // include
671+
)
672+
->willReturn($queryResponse);
673+
674+
$store = new Store($client, 'test-collection');
675+
$documents = iterator_to_array($store->query($queryVector, ['queryTexts' => $queryTexts]));
676+
677+
$this->assertCount(1, $documents);
678+
$this->assertSame('01234567-89ab-cdef-0123-456789abcdef', (string) $documents[0]->id);
679+
$this->assertSame([0.1, 0.2, 0.3], $documents[0]->vector->getData());
680+
$this->assertSame(0.123, $documents[0]->score);
681+
}
644682
}

src/store/src/Bridge/ChromaDb/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
],
2727
"require": {
2828
"php": ">=8.2",
29-
"codewithkyrian/chromadb-php": "^0.2.1|^0.3|^0.4",
29+
"codewithkyrian/chromadb-php": "^1.0",
3030
"symfony/ai-platform": "@dev",
3131
"symfony/ai-store": "@dev",
3232
"symfony/uid": "^7.3|^8.0"

0 commit comments

Comments
 (0)