A year ago I had a problem: ) reduces the search space dramatically. Precision goes up even when relevance ranking isn't perfect.
GET /api/search?q=kerberoasting&cat=guide&limit=10
3. Fallback matters
Meilisearch goes down. Rarely, but it does. I added a MySQL LIKE fallback that kicks in automatically:
results, err := SearchMeilisearch(query, filters)
if err != nil || len(results) == 0 {
results, err = SearchMySQL(query, filters) // fallback
}
Users never noticed the degradation. That's the goal.
The retrieval part: what "RAG" actually means at this scale
I see a lot of articles about building RAG systems with vector embeddings, chunking strategies, cosine similarity, etc. That's the right approach when your questions are complex and open-ended.
For a domain-specific article corpus with structured metadata, it's overkill. What I actually needed was:
- Fast keyword + semantic-ish retrieval (Meilisearch handles this with its ranking rules)
- A way to surface the right article given a user query
- Context injection into LLM prompts when generating summaries or related content
The architecture ended up being:
User query
→ Meilisearch (retrieval, ~10-30ms)
→ Top 3-5 articles (slug + title + excerpt)
→ LLM prompt context
→ Generated response / enriched content
No vector DB. No embeddings pipeline. No chunking headaches. For 1,600 articles averaging 2,000 words each, this works well.
Honest numbers
| Metric | Before | After |
|---|---|---|
| Avg search latency | 340ms (MySQL LIKE) | 28ms (Meilisearch) |
| Typo tolerance | None | Handles 1-2 char errors |
| Multi-word queries | Poor | Good |
| Index size | N/A | ~12MB |
| Setup time | — | ~2 hours total |
The 12MB index for 1,600+ articles is worth emphasizing — Meilisearch is lean.
What I'd do differently
1. Index full content, not just excerpts
I indexed titles, slugs, excerpts and tags — but not the full article body. This means searching for a technical term that appears deep in an article content returns nothing. I'm fixing this progressively.
2. Add synonyms from day one
Meilisearch has a synonyms API. I should have built a synonyms list for cybersecurity terminology immediately:
{
"AD": ["Active Directory"],
"pentest": ["penetration test", "intrusion test"],
"MFA": ["multi-factor authentication", "2FA"]
}
I added these late, after noticing obvious query misses.
3. Log every failed search
The most valuable dataset I have is the list of searches that returned zero results. It tells you exactly what content you're missing and what synonyms to add. I started logging these to a search_misses table — should have done it from the start.
The takeaway
If you're building a content-heavy site and want good search without a massive infrastructure investment:
- Meilisearch is genuinely good and genuinely easy
- Content quality beats algorithmic cleverness every time
- For domain-specific retrieval, you don't need vector embeddings unless your queries are conversational/open-ended
- Log your zero-result searches — it's free product research
The full search endpoint with category/difficulty/type filters, pagination and Meilisearch/MySQL fallback is about 80 lines of Go. Happy to share if useful.
I run , cloud security and compliance — including 17 free security hardening checklists (PDF + Excel).
SOCIAL SHARE CARD GENERATOR