zakin57 downloadsOpen random notes matched by saved filters written in Obsidian's search query syntax.
Open random notes matched by saved filters, written in (a subset of) Obsidian's own search query syntax.
Obsidian doesn't expose its internal search engine through the public plugin API — there's no documented way to hand it a query string and get back a list of matching files. This plugin ships its own parser/evaluator that follows the same documented operators (see "Supported syntax" below), evaluated directly against each note's content (frontmatter included) plus its tags from the metadata cache. It is a close but not pixel-perfect clone of core search — see "Known differences" below.
| Operator | Meaning | Example |
|---|---|---|
| (bare word) | Note content contains the word | meeting |
"phrase" |
Note content contains the exact phrase | "kickoff meeting" |
/regex/ |
Note content matches the regex (flags allowed, e.g. /foo/i) |
/\d{4}-\d{2}-\d{2}/ |
file: |
Match against the file name | file:.png |
path: |
Match against the full file path | path:"Journal/2026" |
content: |
Match against the full note content (same as bare word) | content:"happy cat" |
tag: |
Note has this tag (nested tags included, e.g. tag:#work matches #work/meeting) |
tag:#idea |
line: |
At least one line matches | line:(mix flour) |
section: |
At least one heading section matches (best-effort split on heading lines) | section:(dog cat) |
block: |
At least one paragraph/block matches (best-effort split on blank lines) | block:(dog cat) |
task: |
At least one task line (- [ ]/- [x]) matches |
task:call |
task-todo: |
At least one unchecked task line matches | task-todo:call |
task-done: |
At least one checked ([x]) task line matches |
task-done:call |
[key] |
Frontmatter property key exists and is truthy |
[status] |
[key:value] |
Frontmatter property key equals value (or contains it, for list properties). Wikilink-valued properties (- "[[Poems]]") match on the link's target/alias text, not the bracket syntax |
[status:Draft], [types:poems] |
[key:v1 OR v2] |
Property equals any of the given values | [status:Draft OR Published] |
OR |
Logical or (must be uppercase, space-separated) | meeting OR work |
- |
Exclude (prefix, no space before the term) | meeting -work |
| (space) | Implicit AND | meeting work |
(...) |
Grouping | meeting (work OR personal) |
field:(a b) |
Distributes the field over each grouped term | tag:(idea work) → has both #idea and #work |
Matching is always case-insensitive, except inside /regex/ literals (add
the i flag yourself if you want a case-insensitive regex).
section: and block: use a simple heuristic (split on heading lines /
blank lines) rather than Obsidian's real block/section parser.content: only look at note content, not the file name —
use file:/path: explicitly if you want to match on the name.[key:value] properties are read with a small built-in YAML frontmatter
parser (not Obsidian's metadataCache, which updates on a debounce and can
briefly miss a property you just added) — it covers scalars, quoted
strings, inline lists ([a, b]), and block lists (- item), but not full
YAML (no nested maps, multi-line strings, anchors, etc.).word: immediately followed by a space (or the end of the
query) — e.g. types: poems — is a query error, not a search: it looks
exactly like an attempted property filter but silently splitting it into
two unrelated bare-word terms (types: and poems, found anywhere in the
file independently) would return a plausible-looking but wrong count. Use
[types:poems] for a real property filter, or quote it — "types: poems"
— to search that literal text as a phrase. foo:bar (no space) still
works as one literal token, e.g. for a URL.npm install
npm run dev # watch build
npm run build # type-check + production build
npm run lint # eslint (typescript-eslint recommended-type-checked)
Copy main.js, manifest.json, and styles.css into
<vault>/.obsidian/plugins/super-smart-random-note/ to install manually, or add
the repo to BRAT.
The settings tab implements Obsidian's declarative getSettingDefinitions()
API (1.13.0+) with the old imperative display() kept as a fallback for
older versions — both paths share the same row-rendering code.
The command-row-plus-modal editing UX is modeled after obsidian-advanced-random-note. obsidian-lottery was also a reference for the general idea of filtered random-note picking.