-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f4eab65
commit eb312ed
Showing
5 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Meilisearch\Contracts; | ||
|
||
class SimilarDocumentsQuery | ||
{ | ||
private int|string $id; | ||
private ?int $offset = null; | ||
private ?int $limit = null; | ||
private ?string $embedder = null; | ||
private ?array $attributesToRetrieve = null; | ||
private ?bool $showRankingScore = null; | ||
private ?bool $showRankingScoreDetails = null; | ||
private ?array $filter = null; | ||
|
||
public function setId(string|int $id): SimilarDocumentsQuery | ||
{ | ||
$this->id = $id; | ||
|
||
return $this; | ||
} | ||
|
||
public function setOffset(?int $offset): SimilarDocumentsQuery | ||
{ | ||
$this->offset = $offset; | ||
|
||
return $this; | ||
} | ||
|
||
public function setLimit(?int $limit): SimilarDocumentsQuery | ||
{ | ||
$this->limit = $limit; | ||
|
||
return $this; | ||
} | ||
|
||
public function setFilter(array $filter): SimilarDocumentsQuery | ||
{ | ||
$this->filter = $filter; | ||
|
||
return $this; | ||
} | ||
|
||
public function setEmbedder(string $embedder): SimilarDocumentsQuery | ||
{ | ||
$this->embedder = $embedder; | ||
|
||
return $this; | ||
} | ||
|
||
public function setAttributesToRetrieve(array $attributesToRetrieve): SimilarDocumentsQuery | ||
{ | ||
$this->attributesToRetrieve = $attributesToRetrieve; | ||
|
||
return $this; | ||
} | ||
|
||
public function setShowRankingScore(?bool $showRankingScore): SimilarDocumentsQuery | ||
{ | ||
$this->showRankingScore = $showRankingScore; | ||
|
||
return $this; | ||
} | ||
|
||
public function setShowRankingScoreDetails(?bool $showRankingScoreDetails): SimilarDocumentsQuery | ||
{ | ||
$this->showRankingScoreDetails = $showRankingScoreDetails; | ||
|
||
return $this; | ||
} | ||
|
||
public function toArray(): array | ||
{ | ||
return array_filter([ | ||
'id' => $this->id, | ||
'offset' => $this->offset, | ||
'limit' => $this->limit, | ||
'filter' => $this->filter, | ||
'embedder' => $this->embedder, | ||
'attributesToRetrieve' => $this->attributesToRetrieve, | ||
'showRankingScore' => $this->showRankingScore, | ||
'showRankingScoreDetails' => $this->showRankingScoreDetails, | ||
], function ($item) { return null !== $item; }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Meilisearch\Search; | ||
|
||
class SimilarDocumentsSearchResult implements \Countable, \IteratorAggregate | ||
{ | ||
/** | ||
* @var array<int, array<string, mixed>> | ||
*/ | ||
private array $hits; | ||
|
||
/** | ||
* `estimatedTotalHits` is the attributes returned by the Meilisearch server | ||
* and its value will not be modified by the methods in this class. | ||
* Please, use `hitsCount` if you want to know the real size of the `hits` array at any time. | ||
*/ | ||
private int $estimatedTotalHits; | ||
private int $hitsCount; | ||
private int $offset; | ||
private int $limit; | ||
private int $processingTimeMs; | ||
|
||
private string $id; | ||
|
||
public function __construct(array $body) | ||
{ | ||
$this->id = $body['id']; | ||
$this->hits = $body['hits'] ?? []; | ||
$this->hitsCount = \count($body['hits']); | ||
$this->processingTimeMs = $body['processingTimeMs']; | ||
$this->offset = $body['offset']; | ||
$this->limit = $body['limit']; | ||
$this->estimatedTotalHits = $body['estimatedTotalHits']; | ||
} | ||
|
||
/** | ||
* Return a new {@see SearchResult} instance. | ||
* | ||
* The $options parameter is an array, and the following keys are accepted: | ||
* - transformHits (callable) | ||
* | ||
* The method does NOT trigger a new search. | ||
*/ | ||
public function applyOptions($options): self | ||
{ | ||
if (\array_key_exists('transformHits', $options) && \is_callable($options['transformHits'])) { | ||
$this->transformHits($options['transformHits']); | ||
} | ||
|
||
return $this; | ||
} | ||
|
||
public function transformHits(callable $callback): self | ||
{ | ||
$this->hits = $callback($this->hits); | ||
$this->hitsCount = \count($this->hits); | ||
|
||
return $this; | ||
} | ||
|
||
public function getHit(int $key, $default = null) | ||
{ | ||
return $this->hits[$key] ?? $default; | ||
} | ||
|
||
/** | ||
* @return array<int, array> | ||
*/ | ||
public function getHits(): array | ||
{ | ||
return $this->hits; | ||
} | ||
|
||
public function getOffset(): int | ||
{ | ||
return $this->offset; | ||
} | ||
|
||
public function getLimit(): int | ||
{ | ||
return $this->limit; | ||
} | ||
|
||
public function getEstimatedTotalHits(): int | ||
{ | ||
return $this->estimatedTotalHits; | ||
} | ||
|
||
public function getProcessingTimeMs(): int | ||
{ | ||
return $this->processingTimeMs; | ||
} | ||
|
||
public function getId(): string | ||
{ | ||
return $this->id; | ||
} | ||
|
||
public function getHitsCount(): int | ||
{ | ||
return $this->hitsCount; | ||
} | ||
|
||
public function toArray(): array | ||
{ | ||
$arr = [ | ||
'id' => $this->id, | ||
'hits' => $this->hits, | ||
'hitsCount' => $this->hitsCount, | ||
'processingTimeMs' => $this->processingTimeMs, | ||
'offset' => $this->offset, | ||
'limit' => $this->limit, | ||
'estimatedTotalHits' => $this->estimatedTotalHits, | ||
]; | ||
|
||
return $arr; | ||
} | ||
|
||
public function toJSON(): string | ||
{ | ||
return json_encode($this->toArray(), JSON_PRETTY_PRINT); | ||
} | ||
|
||
public function getIterator(): \ArrayIterator | ||
{ | ||
return new \ArrayIterator($this->hits); | ||
} | ||
|
||
public function count(): int | ||
{ | ||
return $this->hitsCount; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tests\Endpoints; | ||
|
||
use Meilisearch\Contracts\SimilarDocumentsQuery; | ||
use Meilisearch\Endpoints\Indexes; | ||
use Tests\TestCase; | ||
|
||
final class SimilarDocumentsTest extends TestCase | ||
{ | ||
private Indexes $index; | ||
|
||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
$this->index = $this->createEmptyIndex($this->safeIndexName()); | ||
$this->index->updateDocuments(self::VECTOR_MOVIES); | ||
} | ||
|
||
public function testBasicSearchWithSimilarDocuments(): void | ||
{ | ||
$task = $this->index->updateSettings(['embedders' => ['manual' => ['source' => 'userProvided', 'dimensions' => 3]]]); | ||
$this->client->waitForTask($task['taskUid']); | ||
|
||
$response = $this->index->search('room'); | ||
|
||
self::assertEquals(1, $response->getHitsCount()); | ||
|
||
$documentId = $response->getHit(0)['id']; | ||
$response = $this->index->searchSimilarDocuments( | ||
(new SimilarDocumentsQuery()) | ||
->setId($documentId) | ||
); | ||
|
||
self::assertNotNull($response); | ||
self::assertGreaterThanOrEqual(4, $response->getHitsCount()); | ||
self::assertArrayHasKey('_vectors', $response->getHit(0)); | ||
self::assertArrayHasKey('id', $response->getHit(0)); | ||
self::assertSame($documentId, $response->getId()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters