Files
animethemes-server/app/Scout/Elasticsearch/Api/Query/ElasticQuery.php
T
2025-10-26 03:09:42 -03:00

104 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Scout\Elasticsearch\Api\Query;
use App\Http\Api\Criteria\Search\Criteria;
use Elastic\ScoutDriverPlus\Builders\SearchParametersBuilder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use ReflectionClass;
use RuntimeException;
abstract class ElasticQuery
{
abstract public function build(Criteria $criteria): SearchParametersBuilder;
/**
* Helper function for raw queries. This will create four queries against a text field:
* - Matching the exact phrase (x1.0)
* - Matching all terms (words) (x1.0)
* - Matching at least one term (word) (x0.6)
* - Matching fuzzy (x0.4)
*/
protected function createTextQuery(string $field, string $searchTerm): array
{
return [
[
'match_phrase' => [
$field => [
'query' => $searchTerm,
],
],
],
[
'match' => [
$field => [
'query' => $searchTerm,
'operator' => 'AND',
],
],
],
[
'match' => [
$field => [
'query' => $searchTerm,
'boost' => 0.6,
],
],
],
[
'fuzzy' => [
$field => [
'value' => $searchTerm,
'boost' => 0.4,
],
],
],
];
}
/**
* Helper function for raw queries. This will wrap queries in nested queries.
*/
protected function createNestedQuery(string $nestedResource, array $nestedQueries): array
{
return array_map(
fn (array $nestedQuery): array => [
'nested' => [
'path' => $nestedResource,
'query' => $nestedQuery,
],
],
$nestedQueries
);
}
/**
* Shorthand function for calling `$this->createNestedQuery()` with the output from
* `$this->createTextQuery()`.
*/
protected function createNestedTextQuery(string $nestedResource, string $field, string $searchTerm): array
{
return $this->createNestedQuery($nestedResource, $this->createTextQuery("$nestedResource.$field", $searchTerm));
}
/**
* @throws RuntimeException
*/
public static function getForModel(Model $model): ElasticQuery
{
$query = method_exists($model, 'getElasticQuery')
? $model->getElasticQuery()
: Str::of($model::class)
->replace('Models', 'Scout\\Elasticsearch\\Api\\Query')
->append('Query')
->__toString();
throw_unless(class_exists($query), RuntimeException::class, "Please add the 'getElasticQuery' method to the model ".$model::class);
return new ReflectionClass($query)->newInstance();
}
}