FILTER

Narrow results with boolean expressions.

0/2 done

Theory

FILTER drops bindings that fail a boolean test:

SELECT ?ninja ?age WHERE {
  ?ninja a :Ninja ; :age ?age .
  FILTER(?age >= 18)
}

The operators you'll reach for most often inside FILTER(...):

OperatorDoes
= / !=Equality / inequality on RDF terms
< <= > >=Numeric / date comparison
&& / ||Boolean AND / OR
regex(?s, "^foo")Regex match on a string
lang(?lit) = "en"Match a language tag on a literal
bound(?x)Did this variable get a binding? (esp. OPTIONAL)

Three professional details that trip people up

  1. FILTER scope is the whole group { }, not its position. A FILTER placed anywhere inside a { } applies to every binding the group produces — it is not a line that runs 'at that point'. Move it for readability, but it filters the same set.
  2. Three-valued logic. Comparing an unbound or type-mismatched value yields an error, and a FILTER whose expression errors is treated as false — the row is dropped. FILTER(?age >= 18) silently removes anyone with no :age. Use bound(?age) or COALESCE when that's not what you mean.
  3. FILTER cannot create bindings — only remove rows. To compute a new value, use BIND(expr AS ?v); to constrain to a fixed set, use VALUES or IN. Reaching for FILTER to 'set' a variable is a category error.

Reading in progress · 0 of 2 activities done