Files
newznab-tmux/app/Services/Search/Support/ManticoreIndexRegistry.php
T
2026-07-15 14:22:31 +02:00

134 lines
5.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\Search\Support;
use App\Enums\SecondarySearchIndex;
final class ManticoreIndexRegistry
{
/**
* @return array<string, array{settings: array<string, int|string>, columns: array<string, array<string, mixed>>}>
*/
public static function definitions(): array
{
$settings = self::fullTextSettings();
return [
'releases' => ['settings' => $settings, 'columns' => [
'name' => ['type' => 'text'], 'searchname' => ['type' => 'text'],
'fromname' => ['type' => 'text'], 'filename' => ['type' => 'text'],
'categories_id' => ['type' => 'integer'], 'imdbid' => ['type' => 'string'],
'tmdbid' => ['type' => 'integer'], 'traktid' => ['type' => 'integer'],
'tvdb' => ['type' => 'integer'], 'tvmaze' => ['type' => 'integer'],
'tvrage' => ['type' => 'integer'], 'videos_id' => ['type' => 'integer'],
'movieinfo_id' => ['type' => 'integer'], 'size' => ['type' => 'bigint'],
'postdate_ts' => ['type' => 'bigint'], 'adddate_ts' => ['type' => 'bigint'],
'totalpart' => ['type' => 'integer'], 'grabs' => ['type' => 'integer'],
'passwordstatus' => ['type' => 'bigint'], 'groups_id' => ['type' => 'integer'],
'nzbstatus' => ['type' => 'integer'], 'haspreview' => ['type' => 'bigint'],
]],
'predb' => ['settings' => $settings, 'columns' => [
'title' => ['type' => 'text', 'attribute' => true],
'filename' => ['type' => 'text', 'attribute' => true],
'source' => ['type' => 'string', 'attribute' => true],
]],
'movies' => ['settings' => $settings, 'columns' => [
'imdbid' => ['type' => 'string'], 'tmdbid' => ['type' => 'integer'],
'traktid' => ['type' => 'integer'], 'title' => ['type' => 'text'],
'year' => ['type' => 'text'], 'genre' => ['type' => 'text'],
'actors' => ['type' => 'text'], 'director' => ['type' => 'text'],
'rating' => ['type' => 'text'], 'plot' => ['type' => 'text'],
]],
'tvshows' => ['settings' => $settings, 'columns' => [
'title' => ['type' => 'text'], 'tvdb' => ['type' => 'integer'],
'trakt' => ['type' => 'integer'], 'tvmaze' => ['type' => 'integer'],
'tvrage' => ['type' => 'integer'], 'imdb' => ['type' => 'string'],
'tmdb' => ['type' => 'integer'], 'started' => ['type' => 'text'],
'type' => ['type' => 'integer'],
]],
...self::secondaryDefinitions($settings),
];
}
/** @return array{ranker: string, fields: array<string, int>, fuzzy_distance: int} */
public static function profile(string $logical): array
{
$fields = match ($logical) {
'releases' => ['searchname' => 12, 'name' => 8, 'filename' => 5, 'fromname' => 1],
'predb' => ['title' => 12, 'filename' => 5],
'movies' => ['title' => 12, 'director' => 5, 'actors' => 3, 'genre' => 2, 'plot' => 1],
'tvshows' => ['title' => 12],
'music' => ['title' => 12, 'artist' => 9],
'books' => ['title' => 12, 'author' => 9],
'console' => ['title' => 12],
'steam' => ['name' => 12],
'games', 'anime' => ['title' => 12],
default => [],
};
return ['ranker' => 'sph04', 'fields' => $fields, 'fuzzy_distance' => 2];
}
/** @return list<string> */
public static function autocompleteFields(string $logical): array
{
return match ($logical) {
'releases' => ['searchname', 'name'],
'predb' => ['title', 'filename'],
'movies', 'tvshows', 'music', 'books', 'games', 'console', 'anime' => ['title'],
'steam' => ['name'],
default => [],
};
}
/** @param array<string, string> $configuredIndexes */
public static function logicalName(string $table, array $configuredIndexes = []): ?string
{
foreach ($configuredIndexes as $logical => $configuredTable) {
if ($configuredTable === $table) {
return (string) $logical;
}
}
return str_ends_with($table, '_rt') ? array_search($table, self::defaultTableNames(), true) ?: null : null;
}
/** @return array<string, string> */
public static function defaultTableNames(): array
{
$names = [];
foreach (array_keys(self::definitions()) as $logical) {
$names[$logical] = $logical.'_rt';
}
return $names;
}
/** @return array<string, int|string> */
private static function fullTextSettings(): array
{
return [
'min_prefix_len' => 0,
'min_infix_len' => 2,
'exact_words' => 1,
'index_field_lengths' => 1,
];
}
/**
* @param array<string, int|string> $settings
* @return array<string, array{settings: array<string, int|string>, columns: array<string, array<string, mixed>>}>
*/
private static function secondaryDefinitions(array $settings): array
{
$definitions = [];
foreach (SecondarySearchIndex::cases() as $index) {
$definitions[$index->value] = ['settings' => $settings, 'columns' => $index->manticoreColumns()];
}
return $definitions;
}
}