Skip to content

The whole syntax fits in one sentence: a query is a string of key:value pairs, ANDed together, with an optional leading - to exclude one and an optional comma list inside one to match several. That's it — there's no separate query language to learn beyond the twelve keys themselves, and the fastest way to actually learn them is to build one query up a clause at a time rather than read the list first. That's what the steps below do.

Nothing here requires tagging anything in advance. Several of the keys read facts the app already captured when a folder was indexed — dimensions, file type, the date a file arrived — so a useful query works against a folder that's never had a single tag applied to it.

Step 1: One key is already a working query

Start with the single fact you actually care about right now. type:video on its own returns every clip across every registered folder, no other condition required.

/type:video
typevideo
812 items
One key, no other condition — every clip across every registered folder, indexed the same pass as the stills sitting next to them.

type and ext both narrow by kind: type:image or type:video picks the media, ext:mov or ext:heic picks a specific extension when the broader category is too wide. Either one alone is a complete, valid query.

The two aren't interchangeable, and knowing which to reach for saves a step. type:image covers every still regardless of format — a mixed folder of JPEGs, PNGs and raw files all match — while ext:heic narrows to exactly one format inside that broader category, useful when the question is specifically about how a file was saved rather than what it depicts. Starting with type and adding ext only when the format itself matters is usually the faster order than the reverse.

Step 2: Add a second key and it's ANDed automatically

There's no operator to type for "and" — putting two keys in the same line does it. type:video ext:mov is already narrower than either key alone, and neither key has to know the other exists.

/type:video ext:mov rating:>=4
typevideoextmovrating>=4
63 items
Three keys, no connector typed between them — each one narrows the last, in whatever order they were added.

This is the property that makes the syntax easy to build incrementally: start broad, add a key, look at the count, add another. Nothing about adding a fourth key requires rewriting the first three.

Step 3: Match several values with a comma list

A single key can carry more than one acceptable value. tag:any:portrait,studio matches a file tagged with either one — that's OR, and it only ever applies inside one key's list, never across two different keys.

/tag:any:portrait,studio,lookbook rating:>=3
tagany:portrait,studio,lookbookrating>=3
141 items
Three tags, any one of them qualifying — the comma list is OR; the rating alongside it is a separate, ANDed condition.

Confusing this with two separate clauses is the most common early mistake: tag:portrait tag:studio asks for both tags on the same file, which is a much smaller, much stricter set than tag:any:portrait,studio asking for either.

Step 4: Exclude with a leading dash

A - in front of any key negates it. -is:favourite finds everything that isn't starred; -tag:reference finds everything without that tag; the dash works the same way on every key, not just a special few.

/rating:>=4 -is:favourite
rating>=4notisfavourite
58 items
Good work that hasn't been starred yet — a rating floor and a negated status flag, combined the same way any two keys combine.

Negation composes with everything else already covered: type:image -ext:heic -tag:archived reads as "images, not this format, not this tag," each clause independent of the others.

Step 5: Reach for a range on the numeric and date keys

rating, width, height, added and modified all accept a comparison rather than a bare value: >, >=, <, <=, or a range with .. between two values.

/width:>3000 added:2026-01..2026-03
width>3000added2026-01..2026-03
214 items
One size floor and one date window, both ranges rather than exact matches — neither needs a tag to have ever been applied.

rating:>=4 is doing real comparison work here, not just filtering for the literal value 4 — it's the difference between a rating field and a tag called good, which only ever means "has this exact label or doesn't."

Step 6: Ask about status instead of content

is, has and no all answer yes-or-no questions about a file rather than matching a value. is:favourite and is:video check a flag or a type; has:notes and no:tags check whether something exists at all.

/has:notes no:tags
hasnotesnotags
37 items
Annotated but never tagged — the set that a search built only around tags would never surface, because it's asking whether something exists rather than what it equals.

no: is worth learning early, because it's the only way to name a gap directly — the untagged pile, the unrated pile, the folder nobody has written a note in — rather than guessing at it from a list sorted by name.

Step 7: Scope to one folder without leaving the query line

in: narrows to a specific registered folder without switching workspaces or opening a separate window, which matters once more than one drive or project is registered at once.

/type:image in:~/Volumes/Archive/2023-shoots -is:favourite
typeimagein~/Volumes/Archive/2023-shootsnotisfavourite
96 items
One archived drive, one type, one exclusion — the folder itself is just another key in the same line rather than a separate step.

Dropping in: from a query that already works is usually the fastest way to check whether a file exists somewhere else in the library, rather than reopening each workspace by hand to look.

Step 8: Save the line once it's worth reusing

None of the seven keys above are worth memorising if the useful ones just get retyped every week. The first time a query answers a real question well, save it as a view instead of rebuilding it from scratch the next time the same question comes up.

/type:image tag:any:hero,turnaround rating:>=4 -is:favourite
typeimagetagany:hero,turnaroundrating>=4notisfavourite
58 items
Saved once, reused indefinitely — a view stores this exact text and re-parses it every time it's opened, rather than freezing today's result set.

A saved view stores the query's text, not a snapshot of what currently matches it, which is the detail that makes saving worthwhile at all: renaming a tag next month doesn't leave the view pointing at a name that no longer exists, it just follows the rename the next time the view opens. What that actually is under the hood is worth reading once a handful of queries are worth keeping around permanently rather than typed fresh each time.

Reading a query back before trusting a low count

A query that returns far fewer results than expected is usually not telling you the library is thin — it's usually telling you one clause is wrong. Before assuming a rating floor or a tag genuinely has almost nothing behind it, drop the most recently added clause and check whether the count jumps. Because every key in the line is independent, removing one is a cheap way to isolate which clause was doing the unexpected narrowing, rather than rebuilding the whole query from nothing to find out.

What this looks like against video instead of stills

Every key above behaves identically against type:video — there's no separate syntax for clips, and a query written against stills carries over without translation.

/type:video ext:mov rating:>=3 -has:notes
typevideoextmovrating>=3nothasnotes
41 items
Clips worth keeping, unrated commentary aside — the same seven keys, run against video, work exactly the way they do against a still.

That's a direct consequence of video being indexed on the same pass as images rather than living behind a separate mode: a clip carries a rating, tags and notes the same way a photograph does, so rating:>=3 filters one exactly as literally as it filters the other.

A worked example: five keys, one line

None of the individual steps above is hard on its own; the actual skill is stacking three or four of them into a line that answers a real question in one pass instead of five separate searches.

/type:video ext:mov tag:any:hero,turnaround rating:>=3 added:>2026-04-01 -is:favourite
typevideoextmovtagany:hero,turnaroundrating>=3added>2026-04-01notisfavourite
22 items
Six clauses, one query — clips, one format, either tag, a rating floor, a date window, and not already starred. Each one is independent; dropping any single clause only ever widens the result.

Building a query like that from scratch rarely happens in one attempt. Typing type:video, checking the count, adding rating:>=3, checking again, is a faster path to the right five keys than trying to write the whole line correctly the first time.

Notice, too, that nothing about the order the clauses were typed in changes what the line matches. rating:>=3 type:video and type:video rating:>=3 return the same set, since AND doesn't care about sequence — which means there's no wrong order to build one in, only a slower or faster path to the same five keys.

Building a query against a library you didn't tag yourself

A shared studio drive or an inherited archive comes with a tag vocabulary someone else invented, which turns tag: from a key you already know into one you have to guess at. Typing tag: and letting autocomplete show what actually exists in that workspace turns the guess into a fact — the same query line drives the grid and the autocompleter, so what it suggests is never a stale list, only whatever's currently true of that library.

/type:image tag:approved -tag:archive rating:>=3
typeimagetagapprovednottagarchiverating>=3
89 items
A tag guessed from autocomplete rather than remembered — approved, not archived, decent rating — on a library nobody at this desk built.

This matters most on exactly the library where guessing wrong is easiest: one inherited rather than built, where a tag like approved might mean something specific to whoever set the vocabulary up, and the only honest way to find out is to check what it currently returns rather than assume.

What doesn't work, on purpose

There's no parentheses and no way to OR across two different keys — a query can't ask for "tagged portrait or rated above four" as a single grouped condition, only as two independent, ANDed ones. That's a real limit, and it's the trade the syntax makes for staying representable as a row of deletable chips rather than a nested expression only its author can read back. A key the parser doesn't recognise, and a value with a typo in it, both fall back to plain text rather than an error — the grid never goes blank while a query is still being typed.

Common mistakes worth avoiding

Writing tag:portrait tag:studio when the intent was "either" rather than "both" — that's step 3's mistake, and it's the single most common one. Stacking five clauses when two would isolate the question just as well — each additional key is one more thing that has to be exactly right, and an empty result is more often an over-specified query than a genuinely empty library. And typing a value the app doesn't have — a tag that was renamed, a date format that isn't YYYY-MM-DD — which doesn't error, it just quietly matches nothing, so an unexpectedly low count is worth rereading the query for a typo before assuming the library lacks what you're looking for.

A quieter mistake is reaching for a range where a status flag would do — writing rating:>0 to mean "has been rated at all" instead of -rating:0, or building a date range to approximate "recently added" instead of just sorting by it. The keys above are literal, so the closer a query's wording matches the actual question, the less often the result needs a second look to confirm it's right.

Where this syntax runs into a real limit

Every key above matches a fact that's either true of a file or typed onto it — a type, a tag, a rating, a date. None of it matches on what an image shows. refern can take a phrase like "dramatic lighting" and surface pictures carrying no matching tag at all, because it reads the image itself rather than only the facts recorded about it. That's search by meaning, and there's no key above that does it — this syntax is entirely literal, and a photo nobody ever tagged or rated stays unreachable by content alone, however precisely the rest of the query is built. The full comparison covers what that gap means in practice, honestly, rather than glossing over it.

What to do when the library gets large

None of the keys change at forty thousand files across six drives — the same type:video rating:>=3 works whether it's running against four hundred files or forty thousand, because it reads an index rather than scanning folders live. What does change is which habits pay off: a no:tags view becomes worth checking on a schedule rather than once, in: starts earning its place once more than two or three drives are registered, and a query that used to be one clause often becomes worth splitting into two saved views instead of one longer line, since each half stays reusable on its own in a way a single six-clause query never is.

Speed doesn't degrade with scale either, which is easy to take for granted until it matters: a query against forty thousand indexed files returns as fast as one against four hundred, because both read the same already-built index rather than rescanning folders on the fly. The only cost that grows with a library's size is the one-time first pass when a folder is first registered — never the queries run against it afterward.

How to search without tagging everything first covers the case where none of the tag: examples above apply yet, and building a consistent tag vocabulary is worth reading before the tag: key gets used heavily, since a query is only as good as the tags it's searching. The saved-view habit turns any of the lines above into something that doesn't need retyping, and the wider case for a query line over a folder tree covers why this exists at all if that's still an open question. Or skip ahead and try the syntax against your own folders — thirty days, every feature, no card and no account, is enough to run every key above against a real library rather than the examples here.

Questions

What are all the keys the query line understands?
type, ext, tag, rating, is, has, no, in, width, height, added and modified — twelve keys. Anything outside that set is matched as plain text instead of causing an error.
How do I match more than one tag at once?
A comma list inside one key is OR: tag:any:portrait,studio matches either. Two separate clauses are ANDed instead, so tag:portrait tag:studio needs both on the same file.
Can I group conditions with parentheses?
No. AND across keys, OR inside a comma list, is the whole of it — no nesting. That limit is also what makes a query drawable as a row of chips you can delete one at a time.
What happens if I misspell a key or use one that doesn't exist?
It renders as free text rather than throwing an error, so the grid keeps returning something while you work out the right key instead of going blank mid-search.