Filtering (fq)
fq restricts what the SDK can return. It runs before ranking, so it decides
what is eligible, never the order of what is left. Use it for the rules
your product sets: one section of the site, free articles only, nothing older
than a year.
Think of it as the outer boundary. fq removes content globally, for every
request. Inside what is left, a reader narrows further with
facets, which the SDK handles for you.
For the filter language itself — field matches, ranges, AND, OR, NOT —
see Filter Syntax (fq). This page is about applying it from the
browser.
Set it once
fq is part of the request, so it goes in useApi():
const misocmd = window.misocmd || (window.misocmd = []);
misocmd.push(async () => {
const client = new MisoClient('YOUR_PUBLISHABLE_KEY');
const workflow = client.ui.hybridSearch;
workflow.useApi({
fq: 'custom_attributes.premium:"false"',
});
await client.ui.ready;
});
Every request from that workflow now carries the filter. You do not repeat it per query.
Put it on the context when the feature has one. For Ask, a follow-up answer
is a new workflow, so a filter set on client.ui.ask never reaches it. Set it
on client.ui.asks instead. See
Customize the SDK.
| Workflow | Where the filter goes |
|---|---|
| Ask | client.ui.asks.useApi({ fq }) |
| Hybrid Search | client.ui.hybridSearch.useApi({ fq }) |
| Search | client.ui.search.useApi({ fq }) |
Change it while the page runs
Call useApi() again and run the query again. The new filter replaces the old
one:
document.querySelector('#tab-tech').addEventListener('click', () => {
workflow.useApi({ fq: 'tags:"Science and technology"' });
workflow.query({ q: currentQuery });
});
This is the pattern for section tabs, a "free articles only" toggle, or a date
range control. clearApi() drops everything you set, so keep a base object if
you use it.
What a filter also changes
Facet counts follow the filter. Facets count the results that match, and
fq decides what matches. A tag showing 48 results with no filter shows 21
once fq: custom_attributes.word_count:[300 TO *] applies.
That is the behaviour you want. The counts a reader sees always describe the results they can actually reach.
Answers narrow with it. On Ask and Hybrid Search, fq also restricts the
passages the answer can cite, so the answer and the result list stay
consistent.
fq and reader filters work together
A reader picking a facet does not replace your fq. The two travel in
different fields and both apply:
{
"q": "linux",
"fq": "custom_attributes.word_count:[300 TO *]",
"facet_filters": { "tags": { "terms": ["Computing"] } }
}
So fq is the rule your product enforces, and the reader narrows inside it.
A reader cannot widen past your filter. See Facets.
Common filters
custom_attributes.premium:"false"
tags:"Science and technology"
published_at:[2026-01-01T00:00:00Z TO *]
NOT tags:Sponsored
Quote any value with a space.
tags:Science and technologyreturns nothing and reports no error, because the space ends the value. Writetags:"Science and technology". This is the mistake that costs the most time. See Filter Syntax (fq).
Next
- Filter Syntax (fq) — the full language, with worked examples.
- Facets — let readers filter for themselves.
- Customize the SDK — change what each result looks like.
