mirror of
https://github.com/symfony/ai.git
synced 2026-03-23 23:42:18 +01:00
feature #1298 [Store] Change StoreInterface::add() from variadic to VectorDocument|array parameter (claude)
This PR was merged into the main branch.
Discussion
----------
[Store] Change `StoreInterface::add()` from variadic to `VectorDocument|array` parameter
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| Docs? | yes
| Issues | --
| License | MIT
This change improves backwards compatibility by allowing future parameters to be added to the method signature. With variadic parameters, no additional arguments can be added after the variadic argument per PHP's BC policy.
Thanks for proposing `@stof` 👍
Commits
-------
8d7d919a [Store] Change StoreInterface::add() from variadic to array parameter
This commit is contained in:
1
.github/workflows/run-examples.yaml
vendored
1
.github/workflows/run-examples.yaml
vendored
@@ -60,4 +60,3 @@ jobs:
|
||||
# issue_number: context.issue.number,
|
||||
# name: 'Run examples'
|
||||
# });
|
||||
|
||||
|
||||
25
UPGRADE.md
25
UPGRADE.md
@@ -13,3 +13,28 @@ AI Bundle
|
||||
- private AgentInterface $supportMultiAgent,
|
||||
+ private AgentInterface $support,
|
||||
) {}
|
||||
```
|
||||
|
||||
Store
|
||||
-----
|
||||
|
||||
* The `StoreInterface::add()` method signature has changed from variadic to accept a single document or an array
|
||||
|
||||
*Before:*
|
||||
```php
|
||||
public function add(VectorDocument ...$documents): void;
|
||||
|
||||
// Usage
|
||||
$store->add($document1, $document2);
|
||||
$store->add(...$documents);
|
||||
```
|
||||
|
||||
*After:*
|
||||
```php
|
||||
public function add(VectorDocument|array $documents): void;
|
||||
|
||||
// Usage
|
||||
$store->add($document);
|
||||
$store->add([$document1, $document2]);
|
||||
$store->add($documents);
|
||||
```
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
"nyholm/psr7": "^1.8",
|
||||
"php-http/discovery": "^1.20",
|
||||
"symfony/ai-agent": "^0.1",
|
||||
"symfony/ai-bundle": "^0.1",
|
||||
"symfony/ai-bundle": "^0.2",
|
||||
"symfony/ai-chat": "^0.1",
|
||||
"symfony/ai-chroma-db-store": "^0.1",
|
||||
"symfony/ai-chroma-db-store": "^0.2",
|
||||
"symfony/ai-clock-tool": "^0.1",
|
||||
"symfony/ai-hugging-face-platform": "^0.1",
|
||||
"symfony/ai-open-ai-platform": "^0.1",
|
||||
"symfony/ai-similarity-search-tool": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/ai-wikipedia-tool": "^0.1",
|
||||
"symfony/asset": "^8.0",
|
||||
"symfony/asset-mapper": "^8.0",
|
||||
|
||||
@@ -16,7 +16,7 @@ Stores vectors in a PHP array. Data is not persisted and is lost when the PHP pr
|
||||
use Symfony\AI\Store\InMemory\Store;
|
||||
|
||||
$store = new Store();
|
||||
$store->add($document1, $document2);
|
||||
$store->add([$document1, $document2]);
|
||||
$results = $store->query($vector);
|
||||
|
||||
CacheStore
|
||||
@@ -29,7 +29,7 @@ Stores vectors using a PSR-6 cache implementation. Persistence depends on the ca
|
||||
|
||||
$cache = new FilesystemAdapter();
|
||||
$store = new Store($cache);
|
||||
$store->add($document1, $document2);
|
||||
$store->add([$document1, $document2]);
|
||||
$results = $store->query($vector);
|
||||
|
||||
Distance Strategies
|
||||
|
||||
@@ -28,65 +28,65 @@
|
||||
"symfony/ai-albert-platform": "^0.1",
|
||||
"symfony/ai-anthropic-platform": "^0.1",
|
||||
"symfony/ai-azure-platform": "^0.1",
|
||||
"symfony/ai-azure-search-store": "^0.1",
|
||||
"symfony/ai-azure-search-store": "^0.2",
|
||||
"symfony/ai-bedrock-platform": "^0.1",
|
||||
"symfony/ai-brave-tool": "^0.1",
|
||||
"symfony/ai-cache-message-store": "^0.1",
|
||||
"symfony/ai-cache-store": "^0.1",
|
||||
"symfony/ai-cache-store": "^0.2",
|
||||
"symfony/ai-cartesia-platform": "^0.1",
|
||||
"symfony/ai-cerebras-platform": "^0.1",
|
||||
"symfony/ai-chat": "^0.1",
|
||||
"symfony/ai-chroma-db-store": "^0.1",
|
||||
"symfony/ai-click-house-store": "^0.1",
|
||||
"symfony/ai-chroma-db-store": "^0.2",
|
||||
"symfony/ai-click-house-store": "^0.2",
|
||||
"symfony/ai-clock-tool": "^0.1",
|
||||
"symfony/ai-cloudflare-message-store": "^0.1",
|
||||
"symfony/ai-cloudflare-store": "^0.1",
|
||||
"symfony/ai-cloudflare-store": "^0.2",
|
||||
"symfony/ai-decart-platform": "^0.1",
|
||||
"symfony/ai-deep-seek-platform": "^0.1",
|
||||
"symfony/ai-doctrine-message-store": "^0.1",
|
||||
"symfony/ai-docker-model-runner-platform": "^0.1",
|
||||
"symfony/ai-elasticsearch-store": "^0.1",
|
||||
"symfony/ai-elasticsearch-store": "^0.2",
|
||||
"symfony/ai-eleven-labs-platform": "^0.1",
|
||||
"symfony/ai-gemini-platform": "^0.1",
|
||||
"symfony/ai-generic-platform": "^0.1",
|
||||
"symfony/ai-session-message-store": "^0.1",
|
||||
"symfony/ai-hugging-face-platform": "^0.1",
|
||||
"symfony/ai-lm-studio-platform": "^0.1",
|
||||
"symfony/ai-manticore-search-store": "^0.1",
|
||||
"symfony/ai-maria-db-store": "^0.1",
|
||||
"symfony/ai-manticore-search-store": "^0.2",
|
||||
"symfony/ai-maria-db-store": "^0.2",
|
||||
"symfony/ai-meilisearch-message-store": "^0.1",
|
||||
"symfony/ai-meilisearch-store": "^0.1",
|
||||
"symfony/ai-meilisearch-store": "^0.2",
|
||||
"symfony/ai-meta-platform": "^0.1",
|
||||
"symfony/ai-milvus-store": "^0.1",
|
||||
"symfony/ai-milvus-store": "^0.2",
|
||||
"symfony/ai-mistral-platform": "^0.1",
|
||||
"symfony/ai-mongo-db-message-store": "^0.1",
|
||||
"symfony/ai-mongo-db-store": "^0.1",
|
||||
"symfony/ai-neo4j-store": "^0.1",
|
||||
"symfony/ai-mongo-db-store": "^0.2",
|
||||
"symfony/ai-neo4j-store": "^0.2",
|
||||
"symfony/ai-ollama-platform": "^0.1",
|
||||
"symfony/ai-open-ai-platform": "^0.1",
|
||||
"symfony/ai-open-meteo-tool": "^0.1",
|
||||
"symfony/ai-open-router-platform": "^0.1",
|
||||
"symfony/ai-open-search-store": "^0.1",
|
||||
"symfony/ai-open-search-store": "^0.2",
|
||||
"symfony/ai-perplexity-platform": "^0.1",
|
||||
"symfony/ai-pinecone-store": "^0.1",
|
||||
"symfony/ai-pinecone-store": "^0.2",
|
||||
"symfony/ai-pogocache-message-store": "^0.1",
|
||||
"symfony/ai-postgres-store": "^0.1",
|
||||
"symfony/ai-qdrant-store": "^0.1",
|
||||
"symfony/ai-postgres-store": "^0.2",
|
||||
"symfony/ai-qdrant-store": "^0.2",
|
||||
"symfony/ai-redis-message-store": "^0.1",
|
||||
"symfony/ai-redis-store": "^0.1",
|
||||
"symfony/ai-redis-store": "^0.2",
|
||||
"symfony/ai-scaleway-platform": "^0.1",
|
||||
"symfony/ai-scraper-tool": "^0.1",
|
||||
"symfony/ai-serp-api-tool": "^0.1",
|
||||
"symfony/ai-similarity-search-tool": "^0.1",
|
||||
"symfony/ai-supabase-store": "^0.1",
|
||||
"symfony/ai-supabase-store": "^0.2",
|
||||
"symfony/ai-surreal-db-message-store": "^0.1",
|
||||
"symfony/ai-surreal-db-store": "^0.1",
|
||||
"symfony/ai-surreal-db-store": "^0.2",
|
||||
"symfony/ai-tavily-tool": "^0.1",
|
||||
"symfony/ai-transformers-php-platform": "^0.1",
|
||||
"symfony/ai-typesense-store": "^0.1",
|
||||
"symfony/ai-typesense-store": "^0.2",
|
||||
"symfony/ai-vertex-ai-platform": "^0.1",
|
||||
"symfony/ai-voyage-platform": "^0.1",
|
||||
"symfony/ai-weaviate-store": "^0.1",
|
||||
"symfony/ai-weaviate-store": "^0.2",
|
||||
"symfony/ai-wikipedia-tool": "^0.1",
|
||||
"symfony/ai-youtube-tool": "^0.1",
|
||||
"symfony/console": "^7.4|^8.0",
|
||||
|
||||
@@ -38,60 +38,60 @@
|
||||
"symfony/ai-albert-platform": "^0.1",
|
||||
"symfony/ai-anthropic-platform": "^0.1",
|
||||
"symfony/ai-azure-platform": "^0.1",
|
||||
"symfony/ai-azure-search-store": "^0.1",
|
||||
"symfony/ai-azure-search-store": "^0.2",
|
||||
"symfony/ai-bedrock-platform": "^0.1",
|
||||
"symfony/ai-cache-message-store": "^0.1",
|
||||
"symfony/ai-cache-store": "^0.1",
|
||||
"symfony/ai-cache-store": "^0.2",
|
||||
"symfony/ai-cartesia-platform": "^0.1",
|
||||
"symfony/ai-cerebras-platform": "^0.1",
|
||||
"symfony/ai-chat": "^0.1",
|
||||
"symfony/ai-chroma-db-store": "^0.1",
|
||||
"symfony/ai-click-house-store": "^0.1",
|
||||
"symfony/ai-chroma-db-store": "^0.2",
|
||||
"symfony/ai-click-house-store": "^0.2",
|
||||
"symfony/ai-cloudflare-message-store": "^0.1",
|
||||
"symfony/ai-cloudflare-store": "^0.1",
|
||||
"symfony/ai-cloudflare-store": "^0.2",
|
||||
"symfony/ai-decart-platform": "^0.1",
|
||||
"symfony/ai-deep-seek-platform": "^0.1",
|
||||
"symfony/ai-docker-model-runner-platform": "^0.1",
|
||||
"symfony/ai-doctrine-message-store": "^0.1",
|
||||
"symfony/ai-elasticsearch-store": "^0.1",
|
||||
"symfony/ai-elasticsearch-store": "^0.2",
|
||||
"symfony/ai-eleven-labs-platform": "^0.1",
|
||||
"symfony/ai-gemini-platform": "^0.1",
|
||||
"symfony/ai-generic-platform": "^0.1",
|
||||
"symfony/ai-hugging-face-platform": "^0.1",
|
||||
"symfony/ai-lm-studio-platform": "^0.1",
|
||||
"symfony/ai-manticore-search-store": "^0.1",
|
||||
"symfony/ai-maria-db-store": "^0.1",
|
||||
"symfony/ai-manticore-search-store": "^0.2",
|
||||
"symfony/ai-maria-db-store": "^0.2",
|
||||
"symfony/ai-meilisearch-message-store": "^0.1",
|
||||
"symfony/ai-meilisearch-store": "^0.1",
|
||||
"symfony/ai-meilisearch-store": "^0.2",
|
||||
"symfony/ai-meta-platform": "^0.1",
|
||||
"symfony/ai-milvus-store": "^0.1",
|
||||
"symfony/ai-milvus-store": "^0.2",
|
||||
"symfony/ai-mistral-platform": "^0.1",
|
||||
"symfony/ai-mongo-db-message-store": "^0.1",
|
||||
"symfony/ai-mongo-db-store": "^0.1",
|
||||
"symfony/ai-neo4j-store": "^0.1",
|
||||
"symfony/ai-mongo-db-store": "^0.2",
|
||||
"symfony/ai-neo4j-store": "^0.2",
|
||||
"symfony/ai-ollama-platform": "^0.1",
|
||||
"symfony/ai-open-ai-platform": "^0.1",
|
||||
"symfony/ai-open-router-platform": "^0.1",
|
||||
"symfony/ai-open-search-store": "^0.1",
|
||||
"symfony/ai-open-search-store": "^0.2",
|
||||
"symfony/ai-perplexity-platform": "^0.1",
|
||||
"symfony/ai-pinecone-store": "^0.1",
|
||||
"symfony/ai-pinecone-store": "^0.2",
|
||||
"symfony/ai-pogocache-message-store": "^0.1",
|
||||
"symfony/ai-postgres-store": "^0.1",
|
||||
"symfony/ai-qdrant-store": "^0.1",
|
||||
"symfony/ai-postgres-store": "^0.2",
|
||||
"symfony/ai-qdrant-store": "^0.2",
|
||||
"symfony/ai-redis-message-store": "^0.1",
|
||||
"symfony/ai-redis-store": "^0.1",
|
||||
"symfony/ai-redis-store": "^0.2",
|
||||
"symfony/ai-replicate-platform": "^0.1",
|
||||
"symfony/ai-scaleway-platform": "^0.1",
|
||||
"symfony/ai-session-message-store": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-supabase-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/ai-supabase-store": "^0.2",
|
||||
"symfony/ai-surreal-db-message-store": "^0.1",
|
||||
"symfony/ai-surreal-db-store": "^0.1",
|
||||
"symfony/ai-surreal-db-store": "^0.2",
|
||||
"symfony/ai-transformers-php-platform": "^0.1",
|
||||
"symfony/ai-typesense-store": "^0.1",
|
||||
"symfony/ai-typesense-store": "^0.2",
|
||||
"symfony/ai-vertex-ai-platform": "^0.1",
|
||||
"symfony/ai-voyage-platform": "^0.1",
|
||||
"symfony/ai-weaviate-store": "^0.1",
|
||||
"symfony/ai-weaviate-store": "^0.2",
|
||||
"symfony/expression-language": "^7.3|^8.0",
|
||||
"symfony/security-core": "^7.3|^8.0",
|
||||
"symfony/translation": "^7.3|^8.0"
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
0.2
|
||||
---
|
||||
|
||||
* [BC BREAK] Change `StoreInterface::add()` from variadic to accept array and `VectorDocument`
|
||||
|
||||
0.1
|
||||
---
|
||||
|
||||
|
||||
@@ -37,8 +37,12 @@ final class SearchStore implements StoreInterface
|
||||
) {
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$this->request('index', [
|
||||
'value' => array_map([$this, 'convertToIndexableArray'], $documents),
|
||||
]);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -47,8 +47,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
$this->cache->get($this->cacheKey, static fn (): array => []);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$existingVectors = $this->cache->get($this->cacheKey, static fn (): array => []);
|
||||
|
||||
$newVectors = array_map(static fn (VectorDocument $document): array => [
|
||||
|
||||
@@ -35,11 +35,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanDrop()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter());
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6])));
|
||||
$this->assertCount(3, $result);
|
||||
@@ -53,21 +53,21 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingCosineDistance()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter());
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6])));
|
||||
$this->assertCount(3, $result);
|
||||
$this->assertSame([0.1, 0.1, 0.5], $result[0]->vector->getData());
|
||||
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6])));
|
||||
$this->assertCount(6, $result);
|
||||
@@ -77,13 +77,13 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingCosineDistanceAndReturnCorrectOrder()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter());
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.1, 0.6])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.0, 0.1, 0.6])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6])));
|
||||
$this->assertCount(5, $result);
|
||||
@@ -97,11 +97,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingCosineDistanceWithMaxItems()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter());
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
);
|
||||
]);
|
||||
|
||||
$this->assertCount(1, iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'maxItems' => 1,
|
||||
@@ -111,10 +111,10 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingAngularDistance()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter(), new DistanceCalculator(DistanceStrategy::ANGULAR_DISTANCE));
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 2.0, 3.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 5.0, 7.0])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([1.2, 2.3, 3.4])));
|
||||
|
||||
@@ -125,10 +125,10 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingEuclideanDistance()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter(), new DistanceCalculator(DistanceStrategy::EUCLIDEAN_DISTANCE));
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 5.0, 7.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 2.0, 3.0])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([1.2, 2.3, 3.4])));
|
||||
|
||||
@@ -139,10 +139,10 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingManhattanDistance()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter(), new DistanceCalculator(DistanceStrategy::MANHATTAN_DISTANCE));
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 2.0, 3.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 5.0, 7.0])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([1.2, 2.3, 3.4])));
|
||||
|
||||
@@ -153,10 +153,10 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingChebyshevDistance()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter(), new DistanceCalculator(DistanceStrategy::CHEBYSHEV_DISTANCE));
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 2.0, 3.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 5.0, 7.0])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([1.2, 2.3, 3.4])));
|
||||
|
||||
@@ -167,11 +167,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithFilter()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter());
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['category' => 'products', 'enabled' => true])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['category' => 'articles', 'enabled' => true])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['category' => 'products', 'enabled' => false])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'filter' => fn (VectorDocument $doc) => 'products' === $doc->metadata['category'],
|
||||
@@ -185,12 +185,12 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithFilterAndMaxItems()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter());
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['category' => 'products'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['category' => 'articles'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['category' => 'products'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.0, 0.1, 0.6]), new Metadata(['category' => 'products'])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'filter' => fn (VectorDocument $doc) => 'products' === $doc->metadata['category'],
|
||||
@@ -205,11 +205,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithComplexFilter()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter());
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['price' => 100, 'stock' => 5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['price' => 200, 'stock' => 0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['price' => 50, 'stock' => 10])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'filter' => fn (VectorDocument $doc) => $doc->metadata['price'] <= 150 && $doc->metadata['stock'] > 0,
|
||||
@@ -221,11 +221,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithNestedMetadataFilter()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter());
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['options' => ['size' => 'S', 'color' => 'blue']])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['options' => ['size' => 'M', 'color' => 'blue']])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['options' => ['size' => 'S', 'color' => 'red']])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'filter' => fn (VectorDocument $doc) => 'S' === $doc->metadata['options']['size'],
|
||||
@@ -239,11 +239,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithInArrayFilter()
|
||||
{
|
||||
$store = new Store(new ArrayAdapter());
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['brand' => 'Nike'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['brand' => 'Adidas'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['brand' => 'Generic'])),
|
||||
);
|
||||
]);
|
||||
|
||||
$allowedBrands = ['Nike', 'Adidas', 'Puma'];
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/cache": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -29,8 +29,12 @@ final class Store implements StoreInterface
|
||||
) {
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$ids = [];
|
||||
$vectors = [];
|
||||
$metadata = [];
|
||||
|
||||
@@ -53,7 +53,7 @@ final class StoreTest extends TestCase
|
||||
|
||||
$store = new Store($client, 'test-collection');
|
||||
|
||||
$store->add(...$documents);
|
||||
$store->add($documents);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"php": ">=8.2",
|
||||
"codewithkyrian/chromadb-php": "^1.0",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
@@ -53,8 +53,12 @@ class Store implements ManagedStoreInterface, StoreInterface
|
||||
$this->execute('POST', 'DROP TABLE IF EXISTS {{ table }}');
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
|
||||
foreach ($documents as $document) {
|
||||
|
||||
@@ -107,7 +107,7 @@ final class StoreTest extends TestCase
|
||||
|
||||
$store = new Store($httpClient, 'test_db', 'test_table');
|
||||
|
||||
$store->add($document1, $document2);
|
||||
$store->add([$document1, $document2]);
|
||||
}
|
||||
|
||||
public function testAddThrowsExceptionOnHttpError()
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -57,8 +57,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
$this->request('DELETE', \sprintf('vectorize/v2/indexes/%s', $this->index));
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$payload = array_map(
|
||||
$this->convertToIndexableArray(...),
|
||||
$documents,
|
||||
|
||||
@@ -151,7 +151,7 @@ final class StoreTest extends TestCase
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 400 returned for "https://api.cloudflare.com/client/v4/accounts/foo/vectorize/v2/indexes/random/upsert".');
|
||||
$this->expectExceptionCode(400);
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
}
|
||||
|
||||
public function testStoreCanAdd()
|
||||
@@ -174,7 +174,7 @@ final class StoreTest extends TestCase
|
||||
'random',
|
||||
);
|
||||
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$this->assertSame(1, $mockHttpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -65,8 +65,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
$this->request('DELETE', $this->indexName);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$documentToIndex = fn (VectorDocument $document): array => [
|
||||
'index' => [
|
||||
'_index' => $this->indexName,
|
||||
|
||||
@@ -141,7 +141,7 @@ final class StoreTest extends TestCase
|
||||
]);
|
||||
|
||||
$store = new Store($httpClient, 'http://127.0.0.1:9200', 'foo');
|
||||
$store->add(new VectorDocument(Uuid::v7(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v7(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -58,8 +58,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
/**
|
||||
* @throws \Random\RandomException {@see random_int()}
|
||||
*/
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$payload = array_map(
|
||||
fn (VectorDocument $document): array => [
|
||||
'insert' => [
|
||||
|
||||
@@ -111,7 +111,7 @@ final class StoreTest extends TestCase
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:9308/bulk".');
|
||||
$this->expectExceptionCode(400);
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
}
|
||||
|
||||
public function testStoreCanAdd()
|
||||
@@ -141,7 +141,7 @@ final class StoreTest extends TestCase
|
||||
]);
|
||||
|
||||
$store = new Store($httpClient, 'http://127.0.0.1:9308', 'bar', 'random');
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -101,8 +101,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
return self::fromPdo($pdo, $tableName, $indexName, $vectorFieldName);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$statement = $this->connection->prepare(
|
||||
\sprintf(
|
||||
<<<'SQL'
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"php": ">=8.2",
|
||||
"ext-pdo": "*",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
@@ -70,8 +70,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
]);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$this->request('PUT', \sprintf('indexes/%s/documents', $this->indexName), array_map(
|
||||
$this->convertToIndexableArray(...), $documents)
|
||||
);
|
||||
|
||||
@@ -134,7 +134,7 @@ final class StoreTest extends TestCase
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:7700/indexes/test/documents".');
|
||||
$this->expectExceptionCode(400);
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
}
|
||||
|
||||
public function testStoreCanAdd()
|
||||
@@ -158,7 +158,7 @@ final class StoreTest extends TestCase
|
||||
'test',
|
||||
);
|
||||
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -92,8 +92,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
]);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$this->request('POST', 'v2/vectordb/entities/insert', [
|
||||
'collectionName' => $this->collection,
|
||||
'data' => array_map($this->convertToIndexableArray(...), $documents),
|
||||
|
||||
@@ -143,7 +143,7 @@ final class StoreTest extends TestCase
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:19530/v2/vectordb/entities/insert".');
|
||||
$this->expectExceptionCode(400);
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
}
|
||||
|
||||
public function testStoreCanAdd()
|
||||
@@ -171,7 +171,7 @@ final class StoreTest extends TestCase
|
||||
'test',
|
||||
);
|
||||
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -104,8 +104,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
$this->getCollection()->drop();
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$operations = [];
|
||||
|
||||
foreach ($documents as $document) {
|
||||
|
||||
@@ -90,7 +90,7 @@ final class StoreTest extends TestCase
|
||||
$document1 = new VectorDocument($uuid1, new Vector([0.1, 0.2, 0.3]));
|
||||
$document2 = new VectorDocument($uuid2, new Vector([0.4, 0.5, 0.6]), new Metadata(['title' => 'Test']));
|
||||
|
||||
$store->add($document1, $document2);
|
||||
$store->add([$document1, $document2]);
|
||||
}
|
||||
|
||||
public function testAddWithBulkWrite()
|
||||
@@ -142,7 +142,7 @@ final class StoreTest extends TestCase
|
||||
$document1 = new VectorDocument($uuid1, new Vector([0.1, 0.2, 0.3]));
|
||||
$document2 = new VectorDocument($uuid2, new Vector([0.4, 0.5, 0.6]), new Metadata(['title' => 'Test']));
|
||||
|
||||
$store->add($document1, $document2);
|
||||
$store->add([$document1, $document2]);
|
||||
}
|
||||
|
||||
public function testQueryReturnsDocuments()
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"mongodb/mongodb": "^1.21|^2.0",
|
||||
"psr/log": "^3.0",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
@@ -51,8 +51,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
]);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
foreach ($documents as $document) {
|
||||
$this->request('POST', \sprintf('db/%s/query/v2', $this->databaseName), [
|
||||
'statement' => \sprintf('CREATE (n:%s {id: $id, metadata: $metadata, %s: $embeddings}) RETURN n', $this->nodeName, $this->embeddingsField),
|
||||
|
||||
@@ -187,8 +187,8 @@ final class StoreTest extends TestCase
|
||||
$store = new Store($httpClient, 'http://127.0.0.1:7474', 'symfony', 'symfony', 'symfony', 'symfony', 'symfony');
|
||||
|
||||
$store->setup();
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$this->assertSame(3, $httpClient->getRequestsCount());
|
||||
}
|
||||
@@ -286,7 +286,7 @@ final class StoreTest extends TestCase
|
||||
$store = new Store($httpClient, 'http://127.0.0.1:7474', 'symfony', 'symfony', 'symfony', 'symfony', 'symfony');
|
||||
|
||||
$store->setup();
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$results = iterator_to_array($store->query(new Vector([0.1, 0.2, 0.3])));
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -71,8 +71,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
$this->request('DELETE', $this->indexName);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$documentToIndex = fn (VectorDocument $document): array => [
|
||||
'index' => [
|
||||
'_index' => $this->indexName,
|
||||
|
||||
@@ -143,7 +143,7 @@ final class StoreTest extends TestCase
|
||||
]);
|
||||
|
||||
$store = new Store($httpClient, 'http://127.0.0.1:9200', 'foo');
|
||||
$store->add(new VectorDocument(Uuid::v7(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v7(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -63,8 +63,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$vectors = [];
|
||||
foreach ($documents as $document) {
|
||||
$vectors[] = [
|
||||
|
||||
@@ -98,7 +98,7 @@ final class StoreTest extends TestCase
|
||||
$document1 = new VectorDocument($uuid1, new Vector([0.1, 0.2, 0.3]));
|
||||
$document2 = new VectorDocument($uuid2, new Vector([0.4, 0.5, 0.6]), new Metadata(['title' => 'Second Document']));
|
||||
|
||||
self::createStore($client)->add($document1, $document2);
|
||||
self::createStore($client)->add([$document1, $document2]);
|
||||
}
|
||||
|
||||
public function testAddWithNamespace()
|
||||
@@ -141,7 +141,7 @@ final class StoreTest extends TestCase
|
||||
$client->expects($this->never())
|
||||
->method('data');
|
||||
|
||||
self::createStore($client)->add();
|
||||
self::createStore($client)->add([]);
|
||||
}
|
||||
|
||||
public function testQueryReturnsDocuments()
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"php": ">=8.2",
|
||||
"probots-io/pinecone-php": "^1.0",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
@@ -104,8 +104,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
return self::fromPdo($pdo, $tableName, $vectorFieldName, $distance);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$statement = $this->connection->prepare(
|
||||
\sprintf(
|
||||
'INSERT INTO %1$s (id, metadata, %2$s)
|
||||
|
||||
@@ -94,7 +94,7 @@ final class StoreTest extends TestCase
|
||||
$document1 = new VectorDocument($uuid1, new Vector([0.1, 0.2, 0.3]));
|
||||
$document2 = new VectorDocument($uuid2, new Vector([0.4, 0.5, 0.6]), new Metadata(['title' => 'Second']));
|
||||
|
||||
$store->add($document1, $document2);
|
||||
$store->add([$document1, $document2]);
|
||||
}
|
||||
|
||||
public function testQueryWithoutMaxScore()
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"ext-pdo": "*",
|
||||
"oskarstark/enum-helper": "^1.5",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
@@ -57,8 +57,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
]);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$this->request(
|
||||
'PUT',
|
||||
\sprintf('collections/%s/points', $this->collectionName),
|
||||
|
||||
@@ -147,7 +147,7 @@ final class StoreTest extends TestCase
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:6333/collections/test/points?wait=true".');
|
||||
$this->expectExceptionCode(400);
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
}
|
||||
|
||||
public function testStoreCanAdd()
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -78,8 +78,12 @@ class Store implements ManagedStoreInterface, StoreInterface
|
||||
}
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$this->redis->clearLastError();
|
||||
|
||||
$pipeline = $this->redis->multi(\Redis::PIPELINE);
|
||||
|
||||
@@ -93,7 +93,7 @@ final class StoreTest extends TestCase
|
||||
$document1 = new VectorDocument($uuid1, new Vector([0.1, 0.2, 0.3]));
|
||||
$document2 = new VectorDocument($uuid2, new Vector([0.4, 0.5, 0.6]), new Metadata(['title' => 'Second']));
|
||||
|
||||
$store->add($document1, $document2);
|
||||
$store->add([$document1, $document2]);
|
||||
}
|
||||
|
||||
public function testQueryWithoutMaxScore()
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"ext-redis": "*",
|
||||
"oskarstark/enum-helper": "^1.5",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
@@ -46,8 +46,12 @@ final class Store implements StoreInterface
|
||||
) {
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
if (0 === \count($documents)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class StoreTest extends TestCase
|
||||
$httpClient = new MockHttpClient();
|
||||
$store = $this->createStore($httpClient);
|
||||
|
||||
$store->add();
|
||||
$store->add([]);
|
||||
|
||||
$this->assertSame(0, $httpClient->getRequestsCount());
|
||||
}
|
||||
@@ -65,10 +65,10 @@ class StoreTest extends TestCase
|
||||
$httpClient = new MockHttpClient(new MockResponse('', ['http_code' => 201]));
|
||||
$store = $this->createStore($httpClient);
|
||||
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2]), new Metadata(['a' => '1'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.4]), new Metadata(['b' => '2'])),
|
||||
);
|
||||
]);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
@@ -78,10 +78,10 @@ class StoreTest extends TestCase
|
||||
$httpClient = new MockHttpClient(new MockResponse('', ['http_code' => 201]));
|
||||
$store = $this->createStore($httpClient);
|
||||
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2]), new Metadata(['valid' => true])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1]), new Metadata(['invalid' => true])),
|
||||
);
|
||||
]);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -54,8 +54,12 @@ class Store implements ManagedStoreInterface, StoreInterface
|
||||
));
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
foreach ($documents as $document) {
|
||||
$this->request('POST', \sprintf('key/%s', $this->table), $this->convertToIndexableArray($document));
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ final class StoreTest extends TestCase
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:8000/key/test".');
|
||||
$this->expectExceptionCode(400);
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
}
|
||||
|
||||
public function testStoreCannotAddOnInvalidAddResponse()
|
||||
@@ -214,7 +214,7 @@ final class StoreTest extends TestCase
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:8000/key/test".');
|
||||
$this->expectExceptionCode(400);
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector(array_fill(0, 1275, 0.1))));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector(array_fill(0, 1275, 0.1)))]);
|
||||
}
|
||||
|
||||
public function testStoreCanAdd()
|
||||
@@ -265,7 +265,7 @@ final class StoreTest extends TestCase
|
||||
$store = new Store($httpClient, 'http://127.0.0.1:8000', 'test', 'test', 'test', 'test', 'test');
|
||||
$store->setup();
|
||||
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector(array_fill(0, 1275, 0.1))));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector(array_fill(0, 1275, 0.1)))]);
|
||||
|
||||
$this->assertSame(3, $httpClient->getRequestsCount());
|
||||
}
|
||||
@@ -321,7 +321,7 @@ final class StoreTest extends TestCase
|
||||
$store = new Store($httpClient, 'http://127.0.0.1:8000', 'test', 'test', 'test', 'test', 'test');
|
||||
$store->setup();
|
||||
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector(array_fill(0, 1275, 0.1))));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector(array_fill(0, 1275, 0.1)))]);
|
||||
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:8000/sql".');
|
||||
@@ -398,7 +398,7 @@ final class StoreTest extends TestCase
|
||||
|
||||
$store = new Store($httpClient, 'http://127.0.0.1:8000', 'test', 'test', 'test', 'test', 'test');
|
||||
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector(array_fill(0, 1275, 0.1))));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector(array_fill(0, 1275, 0.1)))]);
|
||||
|
||||
$results = iterator_to_array($store->query(new Vector(array_fill(0, 1275, 0.1))));
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -62,8 +62,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
]);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
foreach ($documents as $document) {
|
||||
$this->request('POST', \sprintf('collections/%s/documents', $this->collection), $this->convertToIndexableArray($document));
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ final class StoreTest extends TestCase
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 400 returned for "http://127.0.0.1:8108/collections/test/documents".');
|
||||
$this->expectExceptionCode(400);
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
}
|
||||
|
||||
public function testStoreCanAdd()
|
||||
@@ -145,7 +145,7 @@ final class StoreTest extends TestCase
|
||||
'test',
|
||||
);
|
||||
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -45,8 +45,12 @@ final class Store implements ManagedStoreInterface, StoreInterface
|
||||
]);
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
$this->request('POST', 'v1/batch/objects', [
|
||||
'fields' => [
|
||||
'ALL',
|
||||
|
||||
@@ -154,7 +154,7 @@ final class StoreTest extends TestCase
|
||||
$this->expectException(ClientException::class);
|
||||
$this->expectExceptionMessage('HTTP 422 returned for "http://127.0.0.1:8080/v1/batch/objects".');
|
||||
$this->expectExceptionCode(422);
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
}
|
||||
|
||||
public function testStoreCanAdd()
|
||||
@@ -180,7 +180,7 @@ final class StoreTest extends TestCase
|
||||
'test',
|
||||
);
|
||||
|
||||
$store->add(new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3])));
|
||||
$store->add([new VectorDocument(Uuid::v4(), new Vector([0.1, 0.2, 0.3]))]);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/ai-platform": "^0.1",
|
||||
"symfony/ai-store": "^0.1",
|
||||
"symfony/ai-store": "^0.2",
|
||||
"symfony/http-client": "^7.3|^8.0",
|
||||
"symfony/uid": "^7.3|^8.0"
|
||||
},
|
||||
|
||||
@@ -42,8 +42,12 @@ class Store implements ManagedStoreInterface, StoreInterface
|
||||
$this->drop();
|
||||
}
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
array_push($this->documents, ...$documents);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,13 +87,13 @@ class Indexer implements IndexerInterface
|
||||
++$counter;
|
||||
|
||||
if ($chunkSize === \count($chunk)) {
|
||||
$this->store->add(...$this->vectorizer->vectorize($chunk, $options['platform_options'] ?? []));
|
||||
$this->store->add($this->vectorizer->vectorize($chunk, $options['platform_options'] ?? []));
|
||||
$chunk = [];
|
||||
}
|
||||
}
|
||||
|
||||
if ([] !== $chunk) {
|
||||
$this->store->add(...$this->vectorizer->vectorize($chunk, $options['platform_options'] ?? []));
|
||||
$this->store->add($this->vectorizer->vectorize($chunk, $options['platform_options'] ?? []));
|
||||
}
|
||||
|
||||
$this->logger->debug('Document processing completed', ['total_documents' => $counter]);
|
||||
|
||||
@@ -19,7 +19,10 @@ use Symfony\AI\Store\Document\VectorDocument;
|
||||
*/
|
||||
interface StoreInterface
|
||||
{
|
||||
public function add(VectorDocument ...$documents): void;
|
||||
/**
|
||||
* @param VectorDocument|VectorDocument[] $documents
|
||||
*/
|
||||
public function add(VectorDocument|array $documents): void;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $options
|
||||
|
||||
@@ -24,8 +24,12 @@ final class TestStore implements StoreInterface
|
||||
|
||||
public int $addCalls = 0;
|
||||
|
||||
public function add(VectorDocument ...$documents): void
|
||||
public function add(VectorDocument|array $documents): void
|
||||
{
|
||||
if ($documents instanceof VectorDocument) {
|
||||
$documents = [$documents];
|
||||
}
|
||||
|
||||
++$this->addCalls;
|
||||
$this->documents = array_merge($this->documents, $documents);
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanDrop()
|
||||
{
|
||||
$store = new Store();
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6])));
|
||||
$this->assertCount(3, $result);
|
||||
@@ -52,21 +52,21 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingCosineDistance()
|
||||
{
|
||||
$store = new Store();
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6])));
|
||||
$this->assertCount(3, $result);
|
||||
$this->assertSame([0.1, 0.1, 0.5], $result[0]->vector->getData());
|
||||
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6])));
|
||||
$this->assertCount(6, $result);
|
||||
@@ -76,13 +76,13 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingCosineDistanceAndReturnCorrectOrder()
|
||||
{
|
||||
$store = new Store();
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.1, 0.6])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.0, 0.1, 0.6])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6])));
|
||||
$this->assertCount(5, $result);
|
||||
@@ -96,11 +96,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingCosineDistanceWithMaxItems()
|
||||
{
|
||||
$store = new Store();
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1])),
|
||||
);
|
||||
]);
|
||||
|
||||
$this->assertCount(1, iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'maxItems' => 1,
|
||||
@@ -110,10 +110,10 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingAngularDistance()
|
||||
{
|
||||
$store = new Store(new DistanceCalculator(DistanceStrategy::ANGULAR_DISTANCE));
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 2.0, 3.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 5.0, 7.0])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([1.2, 2.3, 3.4])));
|
||||
|
||||
@@ -124,10 +124,10 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingEuclideanDistance()
|
||||
{
|
||||
$store = new Store(new DistanceCalculator(DistanceStrategy::EUCLIDEAN_DISTANCE));
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 5.0, 7.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 2.0, 3.0])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([1.2, 2.3, 3.4])));
|
||||
|
||||
@@ -138,10 +138,10 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingManhattanDistance()
|
||||
{
|
||||
$store = new Store(new DistanceCalculator(DistanceStrategy::MANHATTAN_DISTANCE));
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 2.0, 3.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 5.0, 7.0])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([1.2, 2.3, 3.4])));
|
||||
|
||||
@@ -152,10 +152,10 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchUsingChebyshevDistance()
|
||||
{
|
||||
$store = new Store(new DistanceCalculator(DistanceStrategy::CHEBYSHEV_DISTANCE));
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 2.0, 3.0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([1.0, 5.0, 7.0])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([1.2, 2.3, 3.4])));
|
||||
|
||||
@@ -166,11 +166,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithFilter()
|
||||
{
|
||||
$store = new Store();
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['category' => 'products', 'enabled' => true])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['category' => 'articles', 'enabled' => true])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['category' => 'products', 'enabled' => false])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'filter' => fn (VectorDocument $doc) => 'products' === $doc->metadata['category'],
|
||||
@@ -184,12 +184,12 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithFilterAndMaxItems()
|
||||
{
|
||||
$store = new Store();
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['category' => 'products'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['category' => 'articles'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['category' => 'products'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.0, 0.1, 0.6]), new Metadata(['category' => 'products'])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'filter' => fn (VectorDocument $doc) => 'products' === $doc->metadata['category'],
|
||||
@@ -204,11 +204,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithComplexFilter()
|
||||
{
|
||||
$store = new Store();
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['price' => 100, 'stock' => 5])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['price' => 200, 'stock' => 0])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['price' => 50, 'stock' => 10])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'filter' => fn (VectorDocument $doc) => $doc->metadata['price'] <= 150 && $doc->metadata['stock'] > 0,
|
||||
@@ -220,11 +220,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithNestedMetadataFilter()
|
||||
{
|
||||
$store = new Store();
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['options' => ['size' => 'S', 'color' => 'blue']])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['options' => ['size' => 'M', 'color' => 'blue']])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['options' => ['size' => 'S', 'color' => 'red']])),
|
||||
);
|
||||
]);
|
||||
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
'filter' => fn (VectorDocument $doc) => 'S' === $doc->metadata['options']['size'],
|
||||
@@ -238,11 +238,11 @@ final class StoreTest extends TestCase
|
||||
public function testStoreCanSearchWithInArrayFilter()
|
||||
{
|
||||
$store = new Store();
|
||||
$store->add(
|
||||
$store->add([
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.1, 0.1, 0.5]), new Metadata(['brand' => 'Nike'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.7, -0.3, 0.0]), new Metadata(['brand' => 'Adidas'])),
|
||||
new VectorDocument(Uuid::v4(), new Vector([0.3, 0.7, 0.1]), new Metadata(['brand' => 'Generic'])),
|
||||
);
|
||||
]);
|
||||
|
||||
$allowedBrands = ['Nike', 'Adidas', 'Puma'];
|
||||
$result = iterator_to_array($store->query(new Vector([0.0, 0.1, 0.6]), [
|
||||
|
||||
@@ -41,7 +41,7 @@ final class RetrieverTest extends TestCase
|
||||
);
|
||||
|
||||
$store = new TestStore();
|
||||
$store->add($document1, $document2);
|
||||
$store->add([$document1, $document2]);
|
||||
|
||||
$queryVector = new Vector([0.2, 0.3, 0.4]);
|
||||
$vectorizer = new Vectorizer(
|
||||
|
||||
Reference in New Issue
Block a user