133 lines
4.3 KiB
PHP
133 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace app\controller\Api;
|
|
|
|
use app\service\Search\OpenSearchSearchService;
|
|
use InvalidArgumentException;
|
|
use JsonException;
|
|
use support\Request;
|
|
use support\Response;
|
|
use Throwable;
|
|
|
|
class SearchController
|
|
{
|
|
public function fulltext(Request $request): Response
|
|
{
|
|
try {
|
|
$payload = $this->jsonPayload($request);
|
|
$data = (new OpenSearchSearchService())->fulltext($payload);
|
|
} catch (JsonException $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 400,
|
|
'message' => 'Invalid JSON body.',
|
|
'errors' => ['body' => $exception->getMessage()],
|
|
], 400);
|
|
} catch (InvalidArgumentException $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 422,
|
|
'message' => 'Search request validation failed.',
|
|
'errors' => ['query' => $exception->getMessage()],
|
|
], 422);
|
|
} catch (Throwable $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 500,
|
|
'message' => 'Full-text search failed.',
|
|
'errors' => ['search' => $exception->getMessage()],
|
|
], 500);
|
|
}
|
|
|
|
return $this->jsonResponse([
|
|
'code' => 0,
|
|
'message' => 'Full-text search completed.',
|
|
'data' => $data,
|
|
], 200);
|
|
}
|
|
|
|
public function vector(Request $request): Response
|
|
{
|
|
try {
|
|
$payload = $this->jsonPayload($request);
|
|
$data = (new OpenSearchSearchService())->vector($payload);
|
|
} catch (JsonException $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 400,
|
|
'message' => 'Invalid JSON body.',
|
|
'errors' => ['body' => $exception->getMessage()],
|
|
], 400);
|
|
} catch (InvalidArgumentException $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 422,
|
|
'message' => 'Search request validation failed.',
|
|
'errors' => ['query' => $exception->getMessage()],
|
|
], 422);
|
|
} catch (Throwable $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 500,
|
|
'message' => 'Vector search failed.',
|
|
'errors' => ['search' => $exception->getMessage()],
|
|
], 500);
|
|
}
|
|
|
|
return $this->jsonResponse([
|
|
'code' => 0,
|
|
'message' => 'Vector search completed.',
|
|
'data' => $data,
|
|
], 200);
|
|
}
|
|
|
|
public function hybrid(Request $request): Response
|
|
{
|
|
try {
|
|
$payload = $this->jsonPayload($request);
|
|
$data = (new OpenSearchSearchService())->hybrid($payload);
|
|
} catch (JsonException $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 400,
|
|
'message' => 'Invalid JSON body.',
|
|
'errors' => ['body' => $exception->getMessage()],
|
|
], 400);
|
|
} catch (InvalidArgumentException $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 422,
|
|
'message' => 'Search request validation failed.',
|
|
'errors' => ['query' => $exception->getMessage()],
|
|
], 422);
|
|
} catch (Throwable $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 500,
|
|
'message' => 'Hybrid search failed.',
|
|
'errors' => ['search' => $exception->getMessage()],
|
|
], 500);
|
|
}
|
|
|
|
return $this->jsonResponse([
|
|
'code' => 0,
|
|
'message' => 'Hybrid search completed.',
|
|
'data' => $data,
|
|
], 200);
|
|
}
|
|
|
|
/**
|
|
* @throws JsonException
|
|
*/
|
|
private function jsonPayload(Request $request): array
|
|
{
|
|
$rawBody = trim($request->rawBody());
|
|
if ($rawBody === '') {
|
|
return $request->post();
|
|
}
|
|
|
|
$payload = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
|
|
return is_array($payload) ? $payload : [];
|
|
}
|
|
|
|
private function jsonResponse(array $data, int $status): Response
|
|
{
|
|
return response(
|
|
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR),
|
|
$status,
|
|
['Content-Type' => 'application/json']
|
|
);
|
|
}
|
|
}
|