{"id":182,"date":"2021-10-22T15:18:50","date_gmt":"2021-10-22T12:18:50","guid":{"rendered":"https:\/\/presta.site\/blog\/?p=182"},"modified":"2026-07-24T13:43:55","modified_gmt":"2026-07-24T10:43:55","slug":"using-sphinx-search-in-prestashop","status":"publish","type":"post","link":"https:\/\/presta.site\/blog\/en\/using-sphinx-search-in-prestashop\/","title":{"rendered":"PrestaShop Sphinx Search: Faster Catalog Search on Large Stores"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Native catalog search is fine on small shops. On large catalogs it can lag on every keystroke and every reindex. <strong>PrestaShop Sphinx search<\/strong> moves full-text matching to a dedicated engine so product lookups stay fast while PrestaShop still renders the product cards.<\/p>\n\n\n<!--more-->\n\n\n<p class=\"wp-block-paragraph\">Sphinx is a full-text search server. You index product fields from MySQL, run a search daemon, then override PrestaShop&#8217;s <code class=\"codecolorer text default\"><span class=\"text\">Search::find<\/span><\/code> so storefront queries hit that engine instead of the built-in index. Two lines of the technology matter in practice: <a href=\"https:\/\/sphinxsearch.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Sphinx<\/a> (still developed; current Sphinx 3 builds differ from the classic open-source 2.x packages) and <a href=\"https:\/\/manticoresearch.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Manticore Search<\/a> (an open-source fork of Sphinx 2.x). The install paths and config samples below follow classic Sphinx 2-style packages such as Debian\/Ubuntu <code class=\"codecolorer text default\"><span class=\"text\">sphinxsearch<\/span><\/code>. On Manticore or Sphinx 3, expect different package names, config directories, and listen ports &#8211; keep the same idea (index product IDs, query them from PHP).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Before you commit to a daemon and an override, try the native tools first &#8211; aliases, fuzzy matching, and weights often fix &#8220;bad results&#8221; without new infrastructure. Walk through those in our <a href=\"https:\/\/presta.site\/blog\/en\/quick-guide-to-configuring-prestashop-search\/\">PrestaShop search configuration guide<\/a>. Official option labels for current shops are in the <a href=\"https:\/\/docs.prestashop-project.org\/v.9-documentation\/user-guide\/configuring-shop\/shop-parameters\/search\/search-parameters\" target=\"_blank\" rel=\"noopener noreferrer\">PrestaShop 9 search parameters docs<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When PrestaShop Sphinx search is worth the setup<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sphinx pays off when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Product search or index rebuilds feel slow under real traffic.<\/li>\n<li>You need morphology \/ stemming beyond what Shop Parameters \u2192 Search gives you.<\/li>\n<li>You are comfortable running a small service on the same host (or a nearby one) and keeping an index cron healthy.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Skip it when the catalog is modest and the pain is relevance only &#8211; fix indexing, aliases, and weights first. Also take a <a href=\"https:\/\/presta.site\/blog\/en\/how-to-create-a-backup-in-prestashop\/\">full PrestaShop backup<\/a> before any class override; a bad <code class=\"codecolorer text default\"><span class=\"text\">Search.php<\/span><\/code> can blank the storefront search page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install Sphinx on the server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Package names differ by distro. On Debian\/Ubuntu, if the classic package is available:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get update\nsudo apt-get install sphinxsearch<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That package is still present on several Debian releases, but it is the older Sphinx 2 line &#8211; not Sphinx 3. If <code class=\"codecolorer text default\"><span class=\"text\">sphinxsearch<\/span><\/code> is missing from your repos, or you want a maintained open-source build, install <a href=\"https:\/\/manticoresearch.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Manticore<\/a> from its current Debian\/Ubuntu instructions instead. Avoid pinning ancient <code class=\"codecolorer text default\"><span class=\"text\">.deb<\/span><\/code> filenames copied from old tutorials (for example Wheezy-era Sphinx 2.2 packages) &#8211; grab whatever your distro or vendor documents for today.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Paths below assume a classic layout under <code class=\"codecolorer text default\"><span class=\"text\">\/etc\/sphinxsearch\/<\/span><\/code>. Manticore often uses <code class=\"codecolorer text default\"><span class=\"text\">\/etc\/manticoresearch\/<\/span><\/code>. Note the SQL listen port from your install docs before you point PrestaShop Sphinx search at the daemon (classic Sphinx often used <code class=\"codecolorer text default\"><span class=\"text\">9306<\/span><\/code>; other builds differ).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configure the Sphinx source and index<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Edit the config (often <code class=\"codecolorer text default\"><span class=\"text\">\/etc\/sphinxsearch\/sphinx.conf<\/span><\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nano \/etc\/sphinxsearch\/sphinx.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Define a MySQL source that pulls the fields you want searchable. Replace credentials and table prefix with your shop&#8217;s values (<code class=\"codecolorer text default\"><span class=\"text\">ps_<\/span><\/code> is the default PrestaShop prefix):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>source PrestaSite\n{\n    type = mysql\n    sql_host = localhost\n    sql_user = DBUSER\n    sql_pass = DBPASSWORD\n    sql_db = DBNAME\n    sql_port = 3306\n    sql_query_pre = SET NAMES utf8mb4\n\n    sql_query = \\\n        SELECT id_product, name, description, description_short \\\n        FROM ps_product_lang\n}\n\nindex PrestaSite\n{\n    source = PrestaSite\n    path = \/var\/lib\/sphinxsearch\/data\/prestasite\n    morphology = stem_en\n    min_word_len = 1\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first column of <code class=\"codecolorer text default\"><span class=\"text\">sql_query<\/span><\/code> becomes the document ID Sphinx returns &#8211; here that is <code class=\"codecolorer text default\"><span class=\"text\">id_product<\/span><\/code>. The query is intentionally minimal. Multilingual or multistore shops usually filter by <code class=\"codecolorer text default\"><span class=\"text\">id_lang<\/span><\/code> \/ shop, or build one index per language. Leave the indexer and search-daemon blocks at sane defaults unless you know you need custom ports or log paths. On Sphinx 3 or Manticore, the config syntax may look different; map the same pieces (DB credentials, SELECT of product fields, index path).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Build the index and start the search daemon<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Index once, then start the daemon. Classic Sphinx uses <code class=\"codecolorer text default\"><span class=\"text\">indexer<\/span><\/code> \/ <code class=\"codecolorer text default\"><span class=\"text\">searchd<\/span><\/code>; some packages wrap the same steps in <code class=\"codecolorer text default\"><span class=\"text\">systemctl<\/span><\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo indexer --all\nsudo searchd<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Refresh on a schedule so new and edited products appear in results. Hourly is a common starting point. In <code class=\"codecolorer text default\"><span class=\"text\">\/etc\/crontab<\/span><\/code> (system crontab, which includes a username column):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>15 * * * * root indexer --all<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you use a user crontab (<code class=\"codecolorer text default\"><span class=\"text\">crontab -e<\/span><\/code>), drop the <code class=\"codecolorer text default\"><span class=\"text\">root<\/span><\/code> column and call the full path to <code class=\"codecolorer text default\"><span class=\"text\">indexer<\/span><\/code>. Confirm the daemon is listening on the port your config declares. If it fails to start, check permissions on the index <code class=\"codecolorer text default\"><span class=\"text\">path<\/span><\/code> and that nothing else already binds that port. PrestaShop Sphinx search only works once this listener answers MATCH queries.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wire PrestaShop Sphinx search with a Search override<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">PrestaShop still owns product loading, stock, images, and templates. Sphinx only returns matching product IDs. You override <code class=\"codecolorer text default\"><span class=\"text\">Search::find<\/span><\/code> so those IDs come from Sphinx, then run a normal product SQL for the current language and shop.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On current PrestaShop releases (1.7 through 9), <code class=\"codecolorer text default\"><span class=\"text\">Search::find<\/span><\/code> still takes a similar argument list, but the method body, fuzzy-search handling, and product SQL have changed a lot since 1.6. Do not drop an old override file onto a modern shop. Open your shop&#8217;s <code class=\"codecolorer text default\"><span class=\"text\">classes\/Search.php<\/span><\/code>, copy <code class=\"codecolorer text default\"><span class=\"text\">find<\/span><\/code> into <code class=\"codecolorer text default\"><span class=\"text\">\/override\/classes\/Search.php<\/span><\/code>, then replace only the part that resolves matching product IDs with a Sphinx\/Manticore query &#8211; keep the rest of the core logic. The PHP below is a <strong>simplified illustration<\/strong> of that ID swap (SphinxSQL on port <code class=\"codecolorer text default\"><span class=\"text\">9306<\/span><\/code>, index name <code class=\"codecolorer text default\"><span class=\"text\">PrestaSite<\/span><\/code>), not a paste-ready override for PrestaShop 9.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\/\/ Illustration only - adapt against your shop's classes\/Search.php\n\nprotected static function getSphinxResults($search_query, $offset, $page_size)\n{\n    $results = array();\n    $total = 0;\n\n    if (!$search_query) {\n        return null;\n    }\n\n    \/\/ Port and index name must match your Sphinx\/Manticore config\n    $link = @mysqli_connect('127.0.0.1', '', '', '', 9306);\n    if (!$link) {\n        return array('results' =&gt; $results, 'total' =&gt; $total);\n    }\n\n    $query = 'SELECT id FROM `PrestaSite` WHERE MATCH(\\''.pSQL($search_query).'\\') LIMIT '.(int)$offset.', '.(int)$page_size;\n    if ($result = $link-&gt;query($query)) {\n        while ($row = $result-&gt;fetch_assoc()) {\n            if (isset($row['id'])) {\n                $results[] = (int) $row['id'];\n            }\n        }\n        $result-&gt;close();\n    }\n\n    $query_total = 'SELECT count(*) AS c FROM `PrestaSite` WHERE MATCH(\\''.pSQL($search_query).'\\')';\n    if ($result = $link-&gt;query($query_total)) {\n        $total = (int) $result-&gt;fetch_assoc()['c'];\n        if ($total &gt; 1000) {\n            $total = 1000;\n        }\n        $result-&gt;close();\n    }\n\n    mysqli_close($link);\n\n    return array('results' =&gt; $results, 'total' =&gt; $total);\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In your override of <code class=\"codecolorer text default\"><span class=\"text\">find<\/span><\/code>, call that helper, then restrict the core product query with <code class=\"codecolorer text default\"><span class=\"text\">WHERE p.id_product IN (...)<\/span><\/code> using the returned IDs (cast to integers). That is the whole PrestaShop Sphinx search hook: IDs from the daemon, everything else from PrestaShop. Harden for production: escape carefully, prefer prepared statements where the client allows them, and fall back to native search if the daemon is down. After saving the override, clear caches so PrestaShop reloads the class.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Clear cache and verify storefront search<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Clear cache from Advanced Parameters \u2192 Performance (and remove a legacy <code class=\"codecolorer text default\"><span class=\"text\">\/cache\/class_index.php<\/span><\/code> if your install still uses that path).<\/li>\n<li>Confirm the override file is readable and named exactly <code class=\"codecolorer text default\"><span class=\"text\">Search.php<\/span><\/code> under <code class=\"codecolorer text default\"><span class=\"text\">\/override\/classes\/<\/span><\/code>.<\/li>\n<li>Search for a known product name in a private window.<\/li>\n<li>If you get a blank page after the override, treat it like any fatal PHP error &#8211; see our <a href=\"https:\/\/presta.site\/blog\/en\/white-screen-of-death-in-prestashop-a-step-by-step-guide\/\">white screen of death checklist<\/a>, then restore the backup if needed.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">PrestaShop Sphinx search is infrastructure, not a Back Office toggle. Keep the indexer cron honest, watch disk for the index path, and revisit native search settings whenever relevance &#8211; not speed &#8211; is the real complaint.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Set up PrestaShop Sphinx search to speed product queries on large catalogs. Install Sphinx, index products, and wire a Search override.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[],"class_list":["post-182","post","type-post","status-publish","format-standard","hentry","category-development"],"_links":{"self":[{"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/posts\/182","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/comments?post=182"}],"version-history":[{"count":20,"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/posts\/182\/revisions"}],"predecessor-version":[{"id":1980,"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/posts\/182\/revisions\/1980"}],"wp:attachment":[{"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/media?parent=182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/categories?post=182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/presta.site\/blog\/wp-json\/wp\/v2\/tags?post=182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}