Knowledge Base

Search the Knowledge Base

Edit

Three different surfaces let users and authors search the Knowledge Base. They all hit the same backend endpoint and apply the same MySQL FULLTEXT ranking — only the UI differs.

The three search entry points

SurfaceWhereReturns
Public reader hubSearch bar at the top of /Up to 50 articles, ranked by relevance, opening at /a/<slug>.
Chat-widget Help tabSearch input at the top of the widget — see The chat-widget Help tab.Up to 50 articles, opened inside the widget without leaving the chat.
Agent / APIGET /api/kb/search?q=<query> (no auth)JSON array of { id, slug, title }, sorted by FTS rank.

All three call the same searchPublished() query helper that runs:

SELECT id, slug, title FROM kb_article
 WHERE status = 'PUBLISHED'
   AND MATCH(title, body_html) AGAINST (? IN NATURAL LANGUAGE MODE)
 ORDER BY MATCH(title, body_html) AGAINST (? IN NATURAL LANGUAGE MODE) DESC
 LIMIT 50

What's indexed

The FULLTEXT index sits on kb_article(title, body_html). Both fields contribute to the score:

  • title — the article's headline. A query that matches the title scores higher than the same query matching only the body.
  • body_html — the rendered article body, after sanitisation. Tags themselves don't match — <strong> is invisible to the index — but the text inside them is.
  • The keywords field. It feeds the Related articles panel, not the search index.
  • Drafts and archived articles. Only status = 'PUBLISHED' rows are searchable. See Article statuses field definitions.
  • Folder names. The folder tree is browsed, not searched.
  • Image alt text inside <img> attributes. The text doesn't reach the index because the FULLTEXT parser indexes word tokens between markup, not attribute values.

How natural-language ranking works

MySQL's FULLTEXT in IN NATURAL LANGUAGE MODE ignores stop-words (the, is, of, …), splits on word boundaries, and scores each row by how many query terms appear, weighted by inverse document frequency (rare terms count more). Two practical implications:

  • Single-word queries find the most general match. Searching dashboard returns every article that mentions the word — usually the article literally titled "The Dashboard" comes first because the term is in its title.
  • Multi-word queries narrow. dashboard attendance ranks higher articles that contain both terms close together than articles that have only one.

MySQL's default minimum word length is 3 characters (innodb_ft_min_token_size = 3). Words shorter than 3 characters are silently ignored — searching pdf finds nothing because pdf is exactly 3 characters but dt would be ignored.

Tips for getting good search results

  • Search for nouns, not verbs. "clock in" finds the right article; "how do I clock in" finds the same article plus every article that uses the word "how".
  • Use distinctive words. A query like "setup" or "manage" matches almost everything. "folder rename" or "dead letter" are far more selective.
  • Quotes are not phrase-matching. Natural-language mode treats quotes as ordinary characters. If you need exact-phrase matching, the API endpoint can be enhanced to support BOOLEAN MODE — open an issue.
  • Try synonyms. The index doesn't expand to synonyms. "login" and "sign-in" each find their own subset.

Searching from the agent / a script

curl -s 'https://mydoc24.org/api/kb/search?q=dashboard%20attendance' | jq

Returns:

[
  { "id": 2, "slug": "the-dashboard", "title": "The Dashboard" },
  { "id": 4, "slug": "attendance-status-field-definitions", "title": "Attendance status field definitions" },
  { "id": 3, "slug": "clock-in-and-out-remotely", "title": "Clock in and out remotely" }
]

No X-API-Key header needed — search is a public read endpoint with Access-Control-Allow-Origin: *.

Use this from a script when you want to dedupe before importing — search for an existing slug or title before calling the import endpoint, so you upsert rather than create duplicates.

Different jobs:

ToolInitiated byReturns
SearchThe user, with an explicit query.Articles whose title + body match the query.
RelatedThe system, automatically per article.Other articles in the same folder cluster whose title + body match the current article's keywords + headings.

The two share infrastructure (FULLTEXT, MATCH AGAINST) but differ in who supplies the query. The keywords field is therefore important for discoverability via the Related panel — see The Editor — but it doesn't help raw search.

Related articles