Skip to content

Commit

Permalink
feat(index): SearchResult introduced
Browse files Browse the repository at this point in the history
  • Loading branch information
Guikingone committed Dec 16, 2020
1 parent 4b6f9e4 commit 16ae9b0
Show file tree
Hide file tree
Showing 6 changed files with 524 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

class Client
{
use HandlesDumps;
use HandlesIndex;
use HandlesSystem;
use HandlesDumps;

private $http;

Expand Down
26 changes: 22 additions & 4 deletions src/Endpoints/Indexes.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use MeiliSearch\Endpoints\Delegates\HandlesSettings;
use MeiliSearch\Exceptions\HTTPRequestException;
use MeiliSearch\Exceptions\TimeOutException;
use MeiliSearch\Search\SearchResult;

class Indexes extends Endpoint
{
Expand Down Expand Up @@ -72,7 +73,7 @@ public function show(): ?array

public function update($body): array
{
return $this->http->put(self::PATH.'/'.$this->uid, $body);
return $this->http->put(self::PATH.'/'.$this->uid, $body);
}

public function delete(): array
Expand Down Expand Up @@ -117,14 +118,31 @@ public function waitForPendingUpdate($updateId, $timeoutInMs = 5000, $intervalIn

// Search

public function search($query, array $options = []): array
/**
* @param string $query
*
* @return SearchResult|array
*/
public function search($query, array $searchParams = [], array $options = [])
{
$parameters = array_merge(
['q' => $query],
$options
$searchParams
);

return $this->http->post(self::PATH.'/'.$this->uid.'/search', $parameters);
$result = $this->http->post(self::PATH.'/'.$this->uid.'/search', $parameters);

if (\array_key_exists('raw', $options) && $options['raw']) {
return $result;
}

$searchResult = new SearchResult($result);

if (\array_key_exists('filteringHits', $options) && \is_callable($options['filteringHits'])) {
$searchResult = $searchResult->filter($options['filteringHits']);
}

return $searchResult;
}

// Stats
Expand Down
198 changes: 198 additions & 0 deletions src/Search/SearchResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
<?php

declare(strict_types=1);

namespace MeiliSearch\Search;

use function array_filter;
use ArrayIterator;
use Countable;
use IteratorAggregate;

class SearchResult implements Countable, IteratorAggregate
{
/**
* @var array<int, array<string, mixed>>
*/
private $hits;

/**
* @var int
*/
private $offset;

/**
* @var int
*/
private $limit;

/**
* @var int
*/
private $nbHits;

/**
* @var bool
*/
private $exhaustiveNbHits;

/**
* @var int
*/
private $processingTimeMs;

/**
* @var string
*/
private $query;

/**
* @var bool|null
*/
private $exhaustiveFacetsCount;

/**
* @var array<string, mixed>
*/
private $facetsDistribution;

/**
* @var array<string, mixed>
*/
private $raw;

public function __construct(array $body)
{
$this->hits = $body['hits'] ?? [];
$this->offset = $body['offset'];
$this->limit = $body['limit'];
$this->nbHits = $body['nbHits'];
$this->exhaustiveNbHits = $body['exhaustiveNbHits'] ?? false;
$this->processingTimeMs = $body['processingTimeMs'];
$this->query = $body['query'];
$this->exhaustiveFacetsCount = $body['exhaustiveFacetsCount'] ?? null;
$this->facetsDistribution = $body['facetsDistribution'] ?? [];
$this->raw = $body;
}

/**
* Return a new {@see SearchResult} instance with the hits filtered using `array_filter($this->hits, $callback, ARRAY_FILTER_USE_BOTH)`.
*
* The $callback receives both the current hit and the key, in that order.
*
* The method DOES not trigger a new search.
*
* @return SearchResult
*/
public function filter(callable $callback): self
{
$results = array_filter($this->hits, $callback, ARRAY_FILTER_USE_BOTH);

$this->hits = $results;
$this->nbHits = \count($results);

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 getMatches(): int
{
return $this->nbHits;
}

public function getNbHits(): int
{
return \count($this->hits);
}

public function getExhaustiveNbHits(): bool
{
return $this->exhaustiveNbHits;
}

public function getProcessingTimeMs(): int
{
return $this->processingTimeMs;
}

public function getQuery(): string
{
return $this->query;
}

public function getExhaustiveFacetsCount(): ?bool
{
return $this->exhaustiveFacetsCount;
}

/**
* @return array<string, mixed>
*/
public function getFacetsDistribution(): array
{
return $this->facetsDistribution;
}

/**
* Return the original search result.
*
* @return array<string, mixed>
*/
public function getRaw(): array
{
return $this->raw;
}

public function toArray(): array
{
return [
'hits' => $this->hits,
'offset' => $this->offset,
'limit' => $this->limit,
'matches' => $this->nbHits,
'nbHits' => \count($this->hits),
'exhaustiveNbHits' => $this->exhaustiveNbHits,
'processingTimeMs' => $this->processingTimeMs,
'query' => $this->query,
'exhaustiveFacetsCount' => $this->exhaustiveFacetsCount,
'facetsDistribution' => $this->facetsDistribution,
];
}

public function json(): string
{
return \json_encode($this->toArray(), JSON_PRETTY_PRINT);
}

public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->hits);
}

public function count(): int
{
return \count($this->hits);
}
}
2 changes: 1 addition & 1 deletion tests/Endpoints/KeysAndPermissionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function testSearchingIfPublicKeyProvided(): void

$newClient = new Client(self::HOST, $this->getKeys()['public']);
$response = $newClient->getIndex('index')->search('test');
$this->assertArrayHasKey('hits', $response);
$this->assertArrayHasKey('hits', $response->toArray());
}

public function testGetSettingsIfPrivateKeyProvided(): void
Expand Down
Loading

0 comments on commit 16ae9b0

Please sign in to comment.