silvershop-suite / search-meilisearch
Meilisearch engine adapter for silvershop-suite/search: typo-tolerant, relevance-ranked product search via a self-hosted Meilisearch.
Package info
github.com/silvershop-suite/silvershop-search-meilisearch
Type:silverstripe-vendormodule
pkg:composer/silvershop-suite/search-meilisearch
Requires
- php: ^8.3
- guzzlehttp/guzzle: ^7
- silvershop-suite/search: dev-main
- silvershop/core: ^6
- silverstripe/cms: ^6.0
- silverstripe/framework: ^6.0
Requires (Dev)
- cambis/silverstan: ^2.1
- phpunit/phpunit: ^11.3
- silverstripe/sqlite3: ^4
- squizlabs/php_codesniffer: ^3.7
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-19 19:54:51 UTC
README
A Meilisearch engine adapter for
silvershop-suite/search: typo-tolerant, relevance-ranked product
search, as a drop-in replacement for the built-in database backend.
Requirements
silvershop-suite/search^1(the search framework)- A reachable Meilisearch server (self-hosted — a single binary)
Running Meilisearch
Meilisearch is a single binary — download it (docs):
curl -L https://install.meilisearch.com | sh # downloads ./meilisearch
For anything beyond a quick local test, run it under systemd. A system service (/etc/systemd/system/meilisearch.service):
[Unit] Description=Meilisearch After=network.target [Service] Type=simple User=meilisearch Environment=MEILI_MASTER_KEY=change-me-to-a-long-random-key Environment=MEILI_ENV=production Environment=MEILI_DB_PATH=/var/lib/meilisearch/data Environment=MEILI_HTTP_ADDR=127.0.0.1:7700 ExecStart=/usr/local/bin/meilisearch Restart=on-failure [Install] WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now meilisearch
No root? A per-user service works too — put the unit in ~/.config/systemd/user/meilisearch.service (use %h/...
paths and ExecStart=%h/meilisearch), then:
systemctl --user enable --now meilisearch sudo loginctl enable-linger "$USER" # one-time: start it at boot without logging in
Keep Meilisearch bound to localhost (behind your app) and use a long random MEILI_MASTER_KEY in production.
Installation
composer require silvershop-suite/search-meilisearch
Point it at your Meilisearch and make it the active backend:
# .env SS_MEILISEARCH_HOST="http://127.0.0.1:7700" SS_MEILISEARCH_KEY="your-master-or-api-key"
# app/_config/search.yml SilverShop\Search\Backend\BackendRegistry: active_backend: 'meilisearch'
Then build the index:
sake tasks:meilisearch-reindex
Run dev/build?flush=1 first so the config + extension load.
How it works
- Products are indexed on publish and removed on unpublish / delete (
ProductSyncExtension), and themeilisearch-reindextask does a full (re)build plus pushes the index settings. - A search runs against Meilisearch and returns the matching products in Meili's relevance order; the SearchPage
controller paginates them as usual — no change to
silvershop-suite/search. - Indexed fields:
Title,InternalItemID(SKU),Model,Content(searchable, weighted in that order) andBasePrice/CreatedTimestamp/Title(sortable). You get typo-tolerance, relevance ranking and instant-search speed out of the box — the gaps the DB backend has. - A search-engine outage never blocks publishing (sync is guarded); run the reindex task to repair any drift.
Facets
All registered facets (category / price / brand / rating / colour / attributes / stock) work unchanged with the
Meilisearch backend: Meili does the typo-tolerant text match + ranking, then silvershop-suite/search's facet framework
applies the selected filters and counts options over the matched products. No per-facet configuration needed.
Relevance & synonyms
Field weighting — free-text matches rank by field importance: Title, then SKU (InternalItemID), Model,
Content. Reorder via config:
SilverShop\Search\Meilisearch\MeilisearchBackend: searchable_attributes: [Title, InternalItemID, Model, Content]
Synonyms — edit them in the CMS at Settings → Shop → Search synonyms: one group per line, comma-separated
(e.g. tv, television, telly). Every term in a group matches the others. Saving pushes them to Meilisearch
immediately — no reindex needed.
Typo tolerance — the minimum word length before a typo is tolerated. Meilisearch's own defaults (oneTypo 5,
twoTypos 9) give short terms zero tolerance, so a 4-letter query like iPad would never reach iPod. The module
lowers the one-typo threshold to 4 so short-word typos match. Tune per key via config (run the reindex task, or
re-save synonyms, to push it):
SilverShop\Search\Meilisearch\MeilisearchBackend: min_word_size_for_typos: oneTypo: 4 twoTypos: 7
Instant search (autocomplete)
A JSON endpoint for typeahead lives at /<your search page>/instant?q=… (e.g. /search/instant?q=tshi). It returns
the top matches fast, for a theme to render a suggestions dropdown:
{"query":"tshi","results":[{"title":"T-Shirt","link":"/shop/apparel/t-shirt/","price":"$25.00","image":"/…"}]}
Limit via config:
SilverShop\Search\Meilisearch\MeilisearchBackend: instant_limit: 8
Roadmap
- Native Meilisearch
facetDistribution(a performance optimisation for very large catalogs).
License
BSD-3-Clause. See LICENSE.
Credits
Built and maintained by Remy Vaartjes (remy@xd.nl) — part of the SilverShop-Suite.