107 lines
3.4 KiB
PHP
107 lines
3.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Service;
|
||
|
|
|
||
|
|
use App\Message\MeilisearchMessage;
|
||
|
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||
|
|
use Symfony\Component\Messenger\MessageBusInterface;
|
||
|
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||
|
|
|
||
|
|
class MeilisearchService
|
||
|
|
{
|
||
|
|
public function __construct(
|
||
|
|
private HttpClientInterface $httpClient,
|
||
|
|
private MessageBusInterface $bus,
|
||
|
|
#[Autowire(env: 'MEILISEARCH_URL')] private string $url,
|
||
|
|
#[Autowire(env: 'MEILISEARCH_API_KEY')] private string $apiKey,
|
||
|
|
) {}
|
||
|
|
|
||
|
|
public function indexExists(string $index): bool
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
$response = $this->httpClient->request('GET', $this->url . "/indexes/{$index}", [
|
||
|
|
'headers' => ['Authorization' => "Bearer {$this->apiKey}"],
|
||
|
|
]);
|
||
|
|
return $response->getStatusCode() === 200;
|
||
|
|
} catch (\Throwable) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public function createIndexIfNotExists(string $index, string $primaryKey = 'id'): void
|
||
|
|
{
|
||
|
|
if (!$this->indexExists($index)) {
|
||
|
|
$this->createIndex($index, $primaryKey);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public function createIndex(string $index, string $primaryKey = 'id'): void
|
||
|
|
{
|
||
|
|
$this->bus->dispatch(new MeilisearchMessage('createIndex', $index, ['primaryKey' => $primaryKey]));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function deleteIndex(string $index): void
|
||
|
|
{
|
||
|
|
$this->bus->dispatch(new MeilisearchMessage('deleteIndex', $index));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function addDocuments(string $index, array $documents): void
|
||
|
|
{
|
||
|
|
$this->bus->dispatch(new MeilisearchMessage('addDocuments', $index, ['documents' => $documents]));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function updateDocuments(string $index, array $documents): void
|
||
|
|
{
|
||
|
|
$this->bus->dispatch(new MeilisearchMessage('updateDocuments', $index, ['documents' => $documents]));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function deleteDocument(string $index, string|int $documentId): void
|
||
|
|
{
|
||
|
|
$this->bus->dispatch(new MeilisearchMessage('deleteDocument', $index, ['documentId' => $documentId]));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function deleteDocuments(string $index, array $ids): void
|
||
|
|
{
|
||
|
|
$this->bus->dispatch(new MeilisearchMessage('deleteDocuments', $index, ['ids' => $ids]));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function updateSettings(string $index, array $settings): void
|
||
|
|
{
|
||
|
|
$this->bus->dispatch(new MeilisearchMessage('updateSettings', $index, ['settings' => $settings]));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function search(string $index, string $query, array $options = []): array
|
||
|
|
{
|
||
|
|
return $this->request('POST', "/indexes/{$index}/search", array_merge([
|
||
|
|
'q' => $query,
|
||
|
|
], $options));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function getDocument(string $index, string|int $documentId): array
|
||
|
|
{
|
||
|
|
return $this->request('GET', "/indexes/{$index}/documents/{$documentId}");
|
||
|
|
}
|
||
|
|
|
||
|
|
public function request(string $method, string $path, ?array $body = null): array
|
||
|
|
{
|
||
|
|
$options = [
|
||
|
|
'headers' => [
|
||
|
|
'Authorization' => "Bearer {$this->apiKey}",
|
||
|
|
'Content-Type' => 'application/json',
|
||
|
|
],
|
||
|
|
];
|
||
|
|
|
||
|
|
if ($body !== null && $method !== 'GET' && $method !== 'DELETE') {
|
||
|
|
$options['json'] = $body;
|
||
|
|
}
|
||
|
|
|
||
|
|
$response = $this->httpClient->request($method, $this->url . $path, $options);
|
||
|
|
|
||
|
|
if ($response->getStatusCode() === 204) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
|
||
|
|
return $response->toArray(false);
|
||
|
|
}
|
||
|
|
}
|