Search
Meilisearch product search for GoCommerce
A Go package that keeps a Meilisearch index of the catalogue and answers storefront searches from it. A worker pushes what changed every 30 seconds, an operator can rebuild the index from the admin, and the storefront searches through the store without holding a key of its own.
- Search module
- 6 settings
- 2 tests
- 3 API operations
- ext/search-meilisearch
What it does
In the package’s own words it is “the sync and the door”: a worker walks the catalogue and pushes what changed, an operator can ask for a full rebuild, and the storefront searches through the store rather than holding a key — though the search-only key is published for a storefront that wants to talk to Meilisearch directly.
Each active product becomes one document: title, plain-text description, vendor, product type, tags, category, picture, SKUs, option values, the cheapest and dearest active variant, whether anything is in stock, and when it last changed. On a full sync the module creates the index if it is missing and sets what is searched, filtered and sorted on.
It talks to Meilisearch over Go’s standard library — indexing is one POST of a JSON array, searching one POST of a query — and it is configured from the Plugins screen, or from Config for a store that prefers environment variables. Where both say something, the screen wins.
Configuration
Two settings are required: where Meilisearch is, and a key that may write to it. Set them in Config, hand them to the reference binary’s -meilisearch flag through the environment, or type them on the Plugins screen.
| Setting | Environment variable | Required | What it does |
|---|---|---|---|
HostMeilisearch URL | MEILI_HOST | Yes | The Meilisearch address — http://127.0.0.1:7700, or a cloud address. Marked public, so the panel’s value is handed to the storefront through GET /api/plugins. |
APIKeyAPI key | MEILI_API_KEY | Yes | A key allowed to write the index: the master key on a laptop, an admin key in production. The package doc’s example reads it from MEILI_MASTER_KEY; the reference binary reads MEILI_API_KEY. |
SearchKeySearch-only key | MEILI_SEARCH_KEY | No | A search-only key the storefront may hold. The store’s own search route uses it when set, and the API key when not. |
IndexIndex name | — | No | The index to write and search, products by default. Set it on the Plugins screen: the panel field’s own default stands in front of Config, so Config.Index is never read. |
Poll | — | No | How often the worker looks for changed products: 30 seconds when zero, and a negative value turns the worker off for a store that calls Sync itself. Go only. |
Client | — | No | Replaces the HTTP client, which otherwise times out after 30 seconds. Go only. |
The module reads its Config struct, not the environment. The variable names are the ones the package’s own example or the reference binary uses; in your own main() you choose where each value comes from. Where a setting has a panel label, the admin’s settings drawer can hold it too, and a value typed there wins over Config.
Setting it up
- Run MeilisearchBeside your database, or as a hosted instance. Note its URL and a key that may write indexes, and a search-only key if the storefront will query it directly.
- Install the modulePass meilisearch.New to gocommerce.New, as below — or start the reference binary with -meilisearch, which reads MEILI_HOST, MEILI_API_KEY and MEILI_SEARCH_KEY.
- Switch it onWith a host and key in Config it starts switched on. Otherwise enable Meilisearch on the Plugins screen and fill in the URL and key there.
- SearchThe first poll is a full sync. The storefront calls GET /x/meilisearch/search?q=… with optional limit, offset, filter and sort, and gets Meilisearch’s hits back.
main.go
import (
"os"
"github.com/itswadesh/gocommerce/core"
meilisearch "github.com/itswadesh/gocommerce/ext/search-meilisearch"
)
app, err := gocommerce.New(cfg, meilisearch.New(meilisearch.Config{
Host: os.Getenv("MEILI_HOST"),
APIKey: os.Getenv("MEILI_API_KEY"),
SearchKey: os.Getenv("MEILI_SEARCH_KEY"),
})) The package doc’s example with its imports, using the variable names the reference binary reads — the doc itself reads the write key from MEILI_MASTER_KEY. cfg is your gocommerce.Config. Import path github.com/itswadesh/gocommerce/ext/search-meilisearch.
How it works
-
A worker, not a hook
Every 30 seconds the worker sends the products whose updated_at is newer than the last sync. The first poll after start, and every twentieth after that, is a full pass that also removes what the catalogue no longer holds.
-
Archived means removed
A product that is no longer active is deleted from the index on the next pass, so a draft or archived product stops appearing in results without a rebuild.
-
Rebuild from the admin
POST /api/admin/x/meilisearch/reindex runs a full sync on demand. GET /api/admin/x/meilisearch/status reports whether the index is on, configured and in step, with counts and the last error.
-
A search route with no key
GET /x/meilisearch/search takes q, limit (up to 100, 20 by default), offset, filter and sort, queries with the search-only key or the API key, and returns hits, total and processing time. It answers 404 while search is off.
-
Index settings, set for you
A full sync creates the index with id as its primary key and sets searchable attributes (title first, then SKUs, vendor, type, tags, category, options, description), filters and sorts on price, stock, category and the rest.
-
One sync at a time
A sync asked for while another runs in the same process is refused with “a sync is already running” — the reindex route answers 409 — rather than overlapping it.
What it does not do
Read these before an order depends on it. No store is known to run GoCommerce in production yet, so these come from the code, not from anyone’s experience.
- Variant edits wait for a full passThe incremental pass picks products by their own updated_at, and a price or stock change is written to the variant, not the product. It reaches the index at the next full pass — ten minutes at the defaults — or on a manual rebuild.
- Sending is not indexingMeilisearch applies document writes as background tasks. The module sends them and does not wait for those tasks, so the indexed count on the status route is a count of documents sent.
- State lives in the processThe last sync time and the counts are held in memory: a restart forgets them, and its first poll is a full sync. Several instances each run a worker and push the same documents.
- The default language onlyDocuments hold the catalogue’s stored copy. Text from the translations module is not indexed, so a French shopper searches the default language.
- Config values are not publishedHost and search key reach the storefront through GET /api/plugins only when typed into the panel. Values set in Config are used by the store but not handed out.
- Config.Index is ignoredThe panel’s index field has a default of its own, and the module reads the panel first — so an index name set only in Config never takes effect. Name the index on the Plugins screen.
- Five query parametersThe search route passes q, limit, offset, filter and sort, and nothing else — facet counts and highlighting mean querying Meilisearch directly with the search-only key.
FAQ
Questions about the Meilisearch module
Does the storefront need a Meilisearch key?
No. GET /x/meilisearch/search sends the query through the store, using the search-only key or, when there is none, the API key. A storefront that would rather query Meilisearch directly can use the search-only key, which the Plugins screen publishes when it is typed there.
How quickly does a change show up in search?
A change to a product itself goes out on the next poll, 30 seconds by default. A change to a variant’s price or stock waits for the next full pass — every twentieth poll, ten minutes at the defaults — or for a rebuild from the admin.
What does a store without it get?
GET /api/products?q= in the core matches a substring of a product’s title or description: no typo tolerance, no ranking, no filters beyond the listing’s own. This module is what adds a search engine; leave it out and none of its code is in your binary.
Does Svelte Commerce search through it?
Not yet. Svelte Commerce’s GoCommerce connector, version 0.1.0, covers catalogue, cart, checkout and order lookup, not a search index. A storefront you write against the API can call the search route directly.
Is this a Meilisearch partnership?
No. The module calls Meilisearch’s public API on an instance you run or rent. Meilisearch does not endorse GoCommerce, and no store is known to run this module in production yet.
Source
Everything on this page is read from ext/search-meilisearch in the GoCommerce repository, MIT licensed. When this page and the code disagree, the code is right and this page is out of date.Meilisearch is a trademark of its owner; this module talks to its public API and implies no endorsement. See trademarks.
Try it against a store of your own
The one-command stack gives you GoCommerce’s API and admin on your own machine in minutes. Add this module to it and try it on test orders before a real one depends on it.