Update manticoresearch support for latest version changes

This commit is contained in:
DariusIII
2026-06-22 21:12:38 +02:00
parent c2024b75c8
commit 74d874c17b
11 changed files with 58 additions and 34 deletions
+4
View File
@@ -14,6 +14,10 @@ SEARCH_DRIVER=${SEARCH_DRIVER}
MANTICORESEARCH_HOST=${MANTICORESEARCH_HOST} MANTICORESEARCH_HOST=${MANTICORESEARCH_HOST}
MANTICORESEARCH_PORT=${MANTICORESEARCH_PORT} MANTICORESEARCH_PORT=${MANTICORESEARCH_PORT}
MANTICORESEARCH_SCHEME=${MANTICORESEARCH_SCHEME}
MANTICORESEARCH_USERNAME=${MANTICORESEARCH_USERNAME}
MANTICORESEARCH_PASSWORD=${MANTICORESEARCH_PASSWORD}
MANTICORESEARCH_TOKEN=${MANTICORESEARCH_TOKEN}
# ManticoreSearch Fuzzy Search Settings # ManticoreSearch Fuzzy Search Settings
MANTICORESEARCH_FUZZY_ENABLED=${MANTICORESEARCH_FUZZY_ENABLED} MANTICORESEARCH_FUZZY_ENABLED=${MANTICORESEARCH_FUZZY_ENABLED}
MANTICORESEARCH_FUZZY_MAX_DISTANCE=${MANTICORESEARCH_FUZZY_MAX_DISTANCE} MANTICORESEARCH_FUZZY_MAX_DISTANCE=${MANTICORESEARCH_FUZZY_MAX_DISTANCE}
+7
View File
@@ -14,6 +14,13 @@ SEARCH_DRIVER=manticore
# ManticoreSearch Configuration # ManticoreSearch Configuration
MANTICORESEARCH_HOST=localhost MANTICORESEARCH_HOST=localhost
MANTICORESEARCH_PORT=9308 MANTICORESEARCH_PORT=9308
# Use http by default. Set https when Manticore HTTP(S) is served over TLS.
MANTICORESEARCH_SCHEME=http
# Optional for Manticore 27.x built-in auth/authz. Leave blank for anonymous local Docker.
MANTICORESEARCH_USERNAME=
MANTICORESEARCH_PASSWORD=
# Optional bearer token auth. If set, this takes precedence over username/password for HTTP clients.
MANTICORESEARCH_TOKEN=
# fuzzy search settings # fuzzy search settings
MANTICORESEARCH_FUZZY_ENABLED=false MANTICORESEARCH_FUZZY_ENABLED=false
# For high availability, set multiple hosts (comma-separated): "host1:9308,host2:9308" # For high availability, set multiple hosts (comma-separated): "host1:9308,host2:9308"
+21
View File
@@ -53,6 +53,27 @@ Set `COMPOSE_PROFILES` in `.env` to match your `SEARCH_DRIVER`:
Only the selected search service container will start. The other remains Only the selected search service container will start. The other remains
dormant and consumes no resources. dormant and consumes no resources.
### ManticoreSearch Image Updates
Both `docker-compose.yml` and `docker-compose.yml.prod-dist` intentionally use
the unpinned `manticoresearch/manticore` image. This keeps ManticoreSearch on
the latest published Docker image whenever images are pulled, but it also means
production can receive ManticoreSearch changes without a repository diff.
Before pulling and restarting production, validate the new image in staging by
creating indexes, indexing a small batch, and running representative searches,
filters, sorting, pagination, deletes, suggestions, fuzzy searches, and any raw
SQL diagnostics/reconciliation commands.
Manticore Search 27.1.5 is part of the 25.x-27.x release line that introduced
built-in authentication/authorization, sharded tables, conversational search,
vector-search improvements, and replication layout changes. The app does not
enable Manticore auth by default, but if auth is enabled on the server set either
`MANTICORESEARCH_USERNAME`/`MANTICORESEARCH_PASSWORD` or
`MANTICORESEARCH_TOKEN` before running the app, index-creation commands, or raw
HTTP diagnostics. Roll auth out in staging first; anonymous local Docker usage
continues to work with these variables blank.
## Make Targets ## Make Targets
Run `make` or `make help` to see all targets, grouped by section. Run `make` or `make help` to see all targets, grouped by section.
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Console\Commands; namespace App\Console\Commands;
use App\Enums\SecondarySearchIndex; use App\Enums\SecondarySearchIndex;
use App\Services\Search\Support\ManticoreClientFactory;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Manticoresearch\Client; use Manticoresearch\Client;
use Manticoresearch\Exceptions\ResponseException; use Manticoresearch\Exceptions\ResponseException;
@@ -37,15 +38,7 @@ class CreateManticoreIndexes extends Command
$dropExisting = $this->option('drop'); $dropExisting = $this->option('drop');
// Get connection details from config $this->client = ManticoreClientFactory::make(config('search.drivers.manticore', config('manticoresearch', [])));
$host = config('manticoresearch.host', '127.0.0.1');
$port = config('manticoresearch.port', 9308);
// Create client
$this->client = new Client([
'host' => $host,
'port' => $port,
]);
// We'll skip checking for data_dir this way since it may not be accessible via API // We'll skip checking for data_dir this way since it may not be accessible via API
// but instead provide better error handling during index creation // but instead provide better error handling during index creation
+2 -7
View File
@@ -6,6 +6,7 @@ namespace App\Console\Commands;
use App\Services\Search\Support\ElasticsearchClientFactory; use App\Services\Search\Support\ElasticsearchClientFactory;
use App\Services\Search\Support\ElasticsearchResponseHelper; use App\Services\Search\Support\ElasticsearchResponseHelper;
use App\Services\Search\Support\ManticoreClientFactory;
use Elastic\Elasticsearch\Client as ElasticsearchClient; use Elastic\Elasticsearch\Client as ElasticsearchClient;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Manticoresearch\Client as ManticoreClient; use Manticoresearch\Client as ManticoreClient;
@@ -53,13 +54,7 @@ class CreateMediaIndexes extends Command
*/ */
private function createManticoreIndexes(): int private function createManticoreIndexes(): int
{ {
$host = config('search.drivers.manticore.host', '127.0.0.1'); $client = ManticoreClientFactory::make(config('search.drivers.manticore', []));
$port = config('search.drivers.manticore.port', 9308);
$client = new ManticoreClient([
'host' => $host,
'port' => $port,
]);
// Test connection // Test connection
try { try {
+8 -5
View File
@@ -6,6 +6,7 @@ namespace App\Console\Commands;
use App\Facades\Elasticsearch; use App\Facades\Elasticsearch;
use App\Services\Search\Support\ElasticsearchResponseHelper; use App\Services\Search\Support\ElasticsearchResponseHelper;
use App\Services\Search\Support\ManticoreClientFactory;
use Elastic\Elasticsearch\Client as ElasticsearchClient; use Elastic\Elasticsearch\Client as ElasticsearchClient;
use Exception; use Exception;
use GuzzleHttp\Client; use GuzzleHttp\Client;
@@ -140,18 +141,20 @@ class NntmuxCheckIndex extends Command
'anime' => 'anime_rt', 'anime' => 'anime_rt',
default => 'releases_rt', default => 'releases_rt',
}; };
$host = (string) config('search.drivers.manticore.host', '127.0.0.1'); $manticoreConfig = config('search.drivers.manticore', []);
$port = (int) config('search.drivers.manticore.port', 9308); $host = (string) ($manticoreConfig['host'] ?? '127.0.0.1');
$port = (int) ($manticoreConfig['port'] ?? 9308);
$scheme = (string) ($manticoreConfig['scheme'] ?? 'http');
// Use HTTP API endpoint // Use HTTP API endpoint
$baseUrl = "http://{$host}:{$port}"; $baseUrl = "{$scheme}://{$host}:{$port}";
// Check if table exists using HTTP API // Check if table exists using HTTP API
$client = new Client([ $client = new Client(ManticoreClientFactory::guzzleOptions($manticoreConfig, [
'base_uri' => $baseUrl, 'base_uri' => $baseUrl,
'timeout' => 10, 'timeout' => 10,
'http_errors' => false, // Don't throw on HTTP errors 'http_errors' => false, // Don't throw on HTTP errors
]); ]));
// Use raw mode which seems to work // Use raw mode which seems to work
$query = "SELECT COUNT(*) FROM {$indexName}"; $query = "SELECT COUNT(*) FROM {$indexName}";
@@ -6,6 +6,7 @@ namespace App\Console\Commands;
use App\Facades\Search; use App\Facades\Search;
use App\Models\Release; use App\Models\Release;
use App\Services\Search\Support\ManticoreClientFactory;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@@ -75,14 +76,7 @@ class UpdateReleasesIndexSchema extends Command
$this->info('Releases index schema update utility'); $this->info('Releases index schema update utility');
$this->newLine(); $this->newLine();
// Initialize ManticoreSearch client $this->client = ManticoreClientFactory::make(config('search.drivers.manticore', []));
$host = config('search.drivers.manticore.host', '127.0.0.1');
$port = config('search.drivers.manticore.port', 9308);
$this->client = new Client([
'host' => $host,
'port' => $port,
]);
// Test connection // Test connection
try { try {
@@ -15,6 +15,7 @@ use App\Models\Release;
use App\Models\SteamApp; use App\Models\SteamApp;
use App\Models\Video; use App\Models\Video;
use App\Services\Search\Contracts\SearchDriverInterface; use App\Services\Search\Contracts\SearchDriverInterface;
use App\Services\Search\Support\ManticoreClientFactory;
use App\Support\ReleaseSearchIndexDocument; use App\Support\ReleaseSearchIndexDocument;
use App\Support\SecondaryIndexDocuments; use App\Support\SecondaryIndexDocuments;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
@@ -55,8 +56,8 @@ class ManticoreSearchDriver implements SearchDriverInterface
public function __construct(array $config = []) public function __construct(array $config = [])
{ {
$this->config = ! empty($config) ? $config : config('search.drivers.manticore'); $this->config = ! empty($config) ? $config : config('search.drivers.manticore');
$this->connection = ['host' => $this->config['host'], 'port' => $this->config['port']]; $this->connection = ManticoreClientFactory::clientConfig($this->config);
$this->manticoreSearch = new Client($this->connection); $this->manticoreSearch = ManticoreClientFactory::make($this->config);
$this->search = new Search($this->manticoreSearch); $this->search = new Search($this->manticoreSearch);
} }
@@ -2336,7 +2337,6 @@ class ManticoreSearchDriver implements SearchDriverInterface
* *
* @param array<string, mixed> $categoryIds Array of category IDs to filter by * @param array<string, mixed> $categoryIds Array of category IDs to filter by
* @param int $limit Maximum number of results * @param int $limit Maximum number of results
* @return list
* @return array<string, mixed> * @return array<string, mixed>
*/ */
public function searchReleasesByCategory(array $categoryIds, int $limit = 1000): array public function searchReleasesByCategory(array $categoryIds, int $limit = 1000): array
@@ -2397,7 +2397,6 @@ class ManticoreSearchDriver implements SearchDriverInterface
* @param string $searchTerm Search text * @param string $searchTerm Search text
* @param array<string, mixed> $categoryIds Array of category IDs to filter by (empty for all categories) * @param array<string, mixed> $categoryIds Array of category IDs to filter by (empty for all categories)
* @param int $limit Maximum number of results * @param int $limit Maximum number of results
* @return list
* @return array<string, mixed> * @return array<string, mixed>
*/ */
public function searchReleasesWithCategoryFilter(string $searchTerm, array $categoryIds = [], int $limit = 1000): array public function searchReleasesWithCategoryFilter(string $searchTerm, array $categoryIds = [], int $limit = 1000): array
+4
View File
@@ -12,6 +12,10 @@ return [
*/ */
'host' => env('MANTICORESEARCH_HOST', '127.0.0.1'), 'host' => env('MANTICORESEARCH_HOST', '127.0.0.1'),
'port' => env('MANTICORESEARCH_PORT', 9308), 'port' => env('MANTICORESEARCH_PORT', 9308),
'scheme' => env('MANTICORESEARCH_SCHEME', 'http'),
'username' => env('MANTICORESEARCH_USERNAME'),
'password' => env('MANTICORESEARCH_PASSWORD'),
'token' => env('MANTICORESEARCH_TOKEN'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
+4
View File
@@ -27,6 +27,10 @@ return [
'driver' => 'manticore', 'driver' => 'manticore',
'host' => env('MANTICORESEARCH_HOST', '127.0.0.1'), 'host' => env('MANTICORESEARCH_HOST', '127.0.0.1'),
'port' => env('MANTICORESEARCH_PORT', 9308), 'port' => env('MANTICORESEARCH_PORT', 9308),
'scheme' => env('MANTICORESEARCH_SCHEME', 'http'),
'username' => env('MANTICORESEARCH_USERNAME'),
'password' => env('MANTICORESEARCH_PASSWORD'),
'token' => env('MANTICORESEARCH_TOKEN'),
'hosts' => env('MANTICORESEARCH_HOSTS', ''), 'hosts' => env('MANTICORESEARCH_HOSTS', ''),
'retries' => env('MANTICORESEARCH_RETRIES', 2), 'retries' => env('MANTICORESEARCH_RETRIES', 2),
'indexes' => [ 'indexes' => [
+1 -1
View File
@@ -111,7 +111,7 @@ services:
retries: 3 retries: 3
timeout: 5s timeout: 5s
manticore: manticore:
image: manticoresearch/manticore:7.4.6 image: manticoresearch/manticore
profiles: profiles:
- manticore - manticore
environment: environment: