Skip to content

Filtering

The FILTER clause restricts results based on conditions. Filters can use comparisons, logical operators, and built-in functions.

Basic FILTER

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

SELECT ?name ?age
WHERE {
    ?person foaf:name ?name .
    ?person foaf:age ?age
    FILTER(?age > 30)
}

Comparison Operators

Operator Description
= Equal
!= Not equal
< Less than
> Greater than
<= Less than or equal
>= Greater than or equal
SELECT ?name ?age
WHERE {
    ?person foaf:name ?name .
    ?person foaf:age ?age
    FILTER(?age >= 18 && ?age <= 65)
}

Logical Operators

Operator Description
&& Logical AND
\|\| Logical OR
! Logical NOT
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

SELECT ?name
WHERE {
    ?person foaf:name ?name .
    ?person foaf:age ?age
    FILTER(?age > 18 && ?age < 65)
}

SELECT ?name
WHERE {
    ?person foaf:name ?name
    FILTER(!BOUND(?age) || ?age > 0)
}

String Matching

REGEX

SELECT ?name
WHERE {
    ?person foaf:name ?name
    FILTER(REGEX(?name, "^A", "i"))  # Names starting with A (case-insensitive)
}

CONTAINS, STRSTARTS, STRENDS

SELECT ?name
WHERE {
    ?person foaf:name ?name
    FILTER(CONTAINS(?name, "son"))
}

SELECT ?name
WHERE {
    ?person foaf:name ?name
    FILTER(STRSTARTS(?name, "John"))
}

SELECT ?email
WHERE {
    ?person foaf:mbox ?email
    FILTER(STRENDS(STR(?email), ".org"))
}

Type Checking Functions

Function Description
ISIRI(?x) True if IRI
ISBLANK(?x) True if blank node
ISLITERAL(?x) True if literal
ISNUMERIC(?x) True if numeric
BOUND(?x) True if variable is bound
SELECT ?value
WHERE {
    ?s ?p ?value
    FILTER(ISLITERAL(?value) && ISNUMERIC(?value))
}

Language Filtering

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

# Filter by language tag
SELECT ?label
WHERE {
    ?x rdfs:label ?label
    FILTER(LANG(?label) = "en")
}

# Filter for any English variant
SELECT ?label
WHERE {
    ?x rdfs:label ?label
    FILTER(LANGMATCHES(LANG(?label), "en"))
}

Numeric Filtering

PREFIX ex: <http://example.org/>

SELECT ?product ?price
WHERE {
    ?product ex:price ?price
    FILTER(?price > 10 && ?price < 100)
}

# Using numeric functions
SELECT ?value
WHERE {
    ?s ex:measurement ?value
    FILTER(ABS(?value) < 0.5)
}

Date/Time Filtering

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX ex: <http://example.org/>

SELECT ?event ?date
WHERE {
    ?event ex:date ?date
    FILTER(?date > "2024-01-01"^^xsd:date)
}

# Filter by year
SELECT ?event ?date
WHERE {
    ?event ex:date ?date
    FILTER(YEAR(?date) = 2024)
}

EXISTS and NOT EXISTS

EXISTS

True if the pattern has at least one match:

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# People who know someone
SELECT ?name
WHERE {
    ?person foaf:name ?name
    FILTER EXISTS { ?person foaf:knows ?someone }
}

NOT EXISTS

True if the pattern has no matches:

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# People who don't know anyone
SELECT ?name
WHERE {
    ?person foaf:name ?name
    FILTER NOT EXISTS { ?person foaf:knows ?someone }
}

IN and NOT IN

PREFIX ex: <http://example.org/>

# Filter by list of values
SELECT ?person ?status
WHERE {
    ?person ex:status ?status
    FILTER(?status IN ("active", "pending", "approved"))
}

# Exclude values
SELECT ?person ?country
WHERE {
    ?person ex:country ?country
    FILTER(?country NOT IN ("Unknown", "N/A"))
}

Combining Filters

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

SELECT ?name ?age ?country
WHERE {
    ?person foaf:name ?name .
    ?person foaf:age ?age .
    ?person ex:country ?country
    FILTER(
        ?age >= 18 &&
        ?age <= 65 &&
        ?country IN ("USA", "Canada", "UK") &&
        REGEX(?name, "^[A-Z]")
    )
}

Filter Placement

Filters are typically placed after the patterns they reference:

# Good: Filter after relevant patterns
SELECT ?name ?age
WHERE {
    ?person foaf:name ?name .
    ?person foaf:age ?age
    FILTER(?age > 30)
}

# Also valid: Multiple filters
SELECT ?name ?age
WHERE {
    ?person foaf:name ?name
    FILTER(STRLEN(?name) > 3)
    ?person foaf:age ?age
    FILTER(?age > 30)
}