diff --git a/src/Contracts/DocumentsQuery.php b/src/Contracts/DocumentsQuery.php index 2f92cb33..223986ba 100644 --- a/src/Contracts/DocumentsQuery.php +++ b/src/Contracts/DocumentsQuery.php @@ -10,6 +10,7 @@ class DocumentsQuery private int $limit; private array $fields; private array $filter; + private ?bool $retrieveVectors = null; public function setOffset(int $offset): DocumentsQuery { @@ -46,6 +47,16 @@ public function setFilter(array $filter): DocumentsQuery return $this; } + /** + * @param bool|null $retrieveVectors boolean value to show _vector details + */ + public function setRetrieveVectors(?bool $retrieveVectors): DocumentsQuery + { + $this->retrieveVectors = $retrieveVectors; + + return $this; + } + /** * Checks if the $filter attribute has been set. * @@ -84,6 +95,7 @@ public function toArray(): array 'limit' => $this->limit ?? null, 'filter' => $this->filter ?? null, 'fields' => $this->fields(), - ], function ($item) { return null != $item || is_numeric($item); }); + 'retrieveVectors' => (null !== $this->retrieveVectors ? ($this->retrieveVectors ? 'true' : 'false') : null), + ], function ($item) { return null !== $item; }); } } diff --git a/src/Contracts/SimilarDocumentsQuery.php b/src/Contracts/SimilarDocumentsQuery.php index 597d651a..9dbe3a2f 100644 --- a/src/Contracts/SimilarDocumentsQuery.php +++ b/src/Contracts/SimilarDocumentsQuery.php @@ -16,6 +16,7 @@ class SimilarDocumentsQuery private ?array $attributesToRetrieve = null; private ?bool $showRankingScore = null; private ?bool $showRankingScoreDetails = null; + private ?bool $retrieveVectors = null; private ?array $filter = null; /** @@ -97,7 +98,17 @@ public function setShowRankingScoreDetails(?bool $showRankingScoreDetails): Simi } /** - * @return array{id: int|string, offset: non-negative-int, limit: positive-int, filter: array|string>, embedder: non-empty-string, attributesToRetrieve: list, showRankingScore: bool, showRankingScoreDetails: bool} SimilarDocumentsQuery converted to an array with non null fields + * @param bool|null $retrieveVectors boolean value to show _vector details + */ + public function setRetrieveVectors(?bool $retrieveVectors): SimilarDocumentsQuery + { + $this->retrieveVectors = $retrieveVectors; + + return $this; + } + + /** + * @return array{id: int|string, offset: non-negative-int, limit: positive-int, filter: array|string>, embedder: non-empty-string, attributesToRetrieve: list, showRankingScore: bool, showRankingScoreDetails: bool, retrieveVectors: bool} SimilarDocumentsQuery converted to an array with non null fields */ public function toArray(): array { @@ -110,6 +121,7 @@ public function toArray(): array 'attributesToRetrieve' => $this->attributesToRetrieve, 'showRankingScore' => $this->showRankingScore, 'showRankingScoreDetails' => $this->showRankingScoreDetails, + 'retrieveVectors' => $this->retrieveVectors, ], function ($item) { return null !== $item; }); diff --git a/tests/Endpoints/DocumentsTest.php b/tests/Endpoints/DocumentsTest.php index b253bdb0..0b1e3463 100644 --- a/tests/Endpoints/DocumentsTest.php +++ b/tests/Endpoints/DocumentsTest.php @@ -11,6 +11,7 @@ use Meilisearch\Exceptions\InvalidArgumentException; use Meilisearch\Exceptions\InvalidResponseBodyException; use Meilisearch\Exceptions\JsonEncodingException; +use Meilisearch\Http\Client; use Psr\Http\Message\ResponseInterface; use Tests\TestCase; @@ -624,6 +625,28 @@ public function testGetDocumentsWithoutFilterCorrectFieldsFormat(): void ); } + public function testGetDocumentsWithVector(): void + { + $http = new Client($this->host, getenv('MEILISEARCH_API_KEY')); + $http->patch('/experimental-features', ['vectorStore' => true]); + $index = $this->createEmptyIndex($this->safeIndexName('movies')); + + $promise = $index->updateEmbedders(['manual' => ['source' => 'userProvided', 'dimensions' => 3]]); + $this->assertIsValidPromise($promise); + $index->waitForTask($promise['taskUid']); + $promise = $index->updateDocuments(self::VECTOR_MOVIES); + $this->assertIsValidPromise($promise); + $index->waitForTask($promise['taskUid']); + + $response = $index->getDocuments(new DocumentsQuery()); + self::assertArrayNotHasKey('_vectors', $response->getResults()[0]); + $query = (new DocumentsQuery())->setRetrieveVectors(true); + $response = $index->getDocuments($query); + self::assertArrayHasKey('_vectors', $response->getResults()[0]); + + self::assertCount(5, $response); + } + public function testGetDocumentsMessageHintException(): void { $responseMock = $this->createMock(ResponseInterface::class); diff --git a/tests/Endpoints/SearchTest.php b/tests/Endpoints/SearchTest.php index f695743d..60f1eaab 100644 --- a/tests/Endpoints/SearchTest.php +++ b/tests/Endpoints/SearchTest.php @@ -694,14 +694,22 @@ public function testVectorSearch(): void $http->patch('/experimental-features', ['vectorStore' => true]); $index = $this->createEmptyIndex($this->safeIndexName()); - $promise = $index->updateEmbedders(['default' => ['source' => 'userProvided', 'dimensions' => 1]]); + $promise = $index->updateEmbedders(['manual' => ['source' => 'userProvided', 'dimensions' => 3]]); $this->assertIsValidPromise($promise); $index->waitForTask($promise['taskUid']); + $promise = $index->updateDocuments(self::VECTOR_MOVIES); + $this->assertIsValidPromise($promise); + $index->waitForTask($promise['taskUid']); + + $response = $index->search('', ['vector' => [-0.5, 0.3, 0.85], 'hybrid' => ['semanticRatio' => 1.0]]); + + self::assertSame(5, $response->getSemanticHitCount()); + self::assertArrayNotHasKey('_vectors', $response->getHit(0)); - $response = $index->search('', ['vector' => [1], 'hybrid' => ['semanticRatio' => 1.0]]); + $response = $index->search('', ['vector' => [-0.5, 0.3, 0.85], 'hybrid' => ['semanticRatio' => 1.0], 'retrieveVectors' => true]); - self::assertSame(0, $response->getSemanticHitCount()); - self::assertEmpty($response->getHits()); + self::assertSame(5, $response->getSemanticHitCount()); + self::assertArrayHasKey('_vectors', $response->getHit(0)); } public function testShowRankingScoreDetails(): void diff --git a/tests/Endpoints/SimilarDocumentsTest.php b/tests/Endpoints/SimilarDocumentsTest.php index abddf359..20ce0048 100644 --- a/tests/Endpoints/SimilarDocumentsTest.php +++ b/tests/Endpoints/SimilarDocumentsTest.php @@ -32,6 +32,13 @@ public function testBasicSearchWithSimilarDocuments(): void $documentId = $response->getHit(0)['id']; $response = $this->index->searchSimilarDocuments(new SimilarDocumentsQuery($documentId)); + self::assertGreaterThanOrEqual(4, $response->getHitsCount()); + self::assertArrayNotHasKey('_vectors', $response->getHit(0)); + self::assertArrayHasKey('id', $response->getHit(0)); + self::assertSame($documentId, $response->getId()); + + $similarQuery = new SimilarDocumentsQuery($documentId); + $response = $this->index->searchSimilarDocuments($similarQuery->setRetrieveVectors(true)); self::assertGreaterThanOrEqual(4, $response->getHitsCount()); self::assertArrayHasKey('_vectors', $response->getHit(0)); self::assertArrayHasKey('id', $response->getHit(0));