Search
Search lets a site ask one environment's published content a question in words and answers with the pages that match, the heading each match sits under, and a short plain-text snippet.
Why search answers only from what is published
A reader with a question wants the paragraph that answers it, not a page that mentions the word somewhere. So the CMS keeps an index of published content, heading by heading, and a site asks it over the delivery API instead of building its own.
Only published text goes in, so search never shows a reader a draft. The index is a copy that can always be rebuilt from the documents, which is why its one repair is a rebuild. A content manager decides what is findable. An owner decides whether the project has search at all.
How pages are indexed, matched and ranked
What goes in
A Markdown document gives one entry for the whole page, with its title and all of its text, and one for each ## and ### section. The CMS turns it into plain text with the parser that renders it: code stays in, image descriptions and raw HTML blocks stay out. A JSON document gives one entry with its strings, skipping references and file pointers, and a plain-text document gives one entry. Folder settings (_index) and components (_schemas/…) are never indexed. Each environment and each locale has entries of its own.
Searchable is on unless something turns it off. A document set to Inherit takes its folder's setting, which counts once the folder's settings are published. A document's own setting counts as soon as it is saved.
When the index changes
A publish, an unpublish or a delete updates the index before the request answers. A save of content changes nothing; only a save that changes Searchable re-indexes that document. Search is on until an owner turns it off. Off deletes the index in every environment, and the search route answers 404. On rebuilds it in the background.
If the CMS stops between a publish and the index write, the index misses that change until someone rebuilds it. A rebuild walks every published document of one environment, writes its entries again and removes the rest.
How a question is read
A question is 1 to 200 characters: plain words, "a quoted phrase" and -word to exclude a word. A hit needs only one of the plain words, so more words widen the answer; a quoted phrase must appear whole, which narrows it. Each locale is indexed in its own language where the database can stem it, such as English or German. So in English promote and promotions both find promotion, and common words such as the are ignored. Other languages match whole words. There is no fuzzy matching and no prefix matching, so promo and promotoin find nothing.
How hits are ranked
A word in a title weighs ten times as much as a word in the text, and a word in a heading five times. So a page titled Publishing beats one that mentions publishing in a sentence, and a section whose heading names the word beats one that does not. Equal scores put the most recently indexed entry first. One page can answer as a whole and for each matching section.
An answer reaches the first 200 hits: limit is 1 to 50, 10 by default, and offset + limit may not pass 200.
What a hit carries
Each hit has the document's key and title, the heading it was found under and that heading's anchor, a plain-text snippet of up to 180 characters around the first word you typed, a score, and the locale its text is in. On a whole-page hit, heading and anchor are null. The anchor is the id the SDK puts on that heading when it renders with headingIds. score orders one answer and means nothing across two.
Locales and fallback
A search reads the locale it names, or the project's default. Outside the default, it also reads the default, the way delivery falls back. A default-locale hit is kept only when its key has nothing published in the requested locale, and it carries fallbackLocale. Equal scores put the requested locale first.
Search spends the delivery key's read budget, 600 a minute by default. A publish retires every cached search in the environment.
How to
Dashboard
- As an owner, open Settings › Project.
- Under Search, tick or clear Let sites search this project's published content. Clearing it asks Turn search off?; press Turn search off.
- Press Rebuild search index when a result looks out of date. It rebuilds the default environment, named under it, and reports "Indexed 42 documents."
API
Ask a question with a delivery key for the environment:
curl -s -u '<keyId>:<secret>' \
'http://localhost:3000/d/v1/<project>/<env>/search?q=promotion&limit=5'The answer looks like this:
{
"hits": [
{
"key": "docs/publishing",
"title": "Publishing",
"heading": "Promoting an environment",
"anchor": "promoting-an-environment",
"snippet": "Before a promotion, the CMS compares the two environments…",
"score": 3.75,
"locale": "en-GB"
}
],
"total": 12,
"_meta": { "q": "promotion", "locale": "en-GB", "limit": 5, "offset": 0 }
}SDK
// links.ts: each hit as a link, with the locale its text is in.
import { quillet } from '@quilletcms/sdk/node'
const q = quillet()
const answer = await q.search('promotion', { limit: 5 })
for (const hit of answer.hits) {
const href = hit.anchor ? `/${hit.key}/#${hit.anchor}` : `/${hit.key}/`
console.log(href, hit.fallbackLocale ?? hit.locale, hit.snippet)
}Limits
- The dashboard has no full-text search of drafts. The content index's Search filters by title or key, and the work views in Finding work list what is unfinished.
- Text in a document a page references is found under that document's key.
- A word matched through its stem may be missing from the snippet.
- A rebuild runs at most five times an hour per environment.
- The search box on this documentation site is not this feature. The site is static and searches an index built at build time, so it cannot demonstrate delivery search.
Related
- Search index: the switch and the rebuild, step by step.
- Search: searching from a site, marking snippets and paging.
- Delivery API: the search route and its errors.
- Delivery: the API search belongs to, and its cache.
- Finding work: what a content manager uses to find drafts.