A collection of RDF libraries for JavaScript

View the Project on GitHub

« API / Quad Filter Expressions

This document describes a language for expressing filters on RDF data at the quad-level, allowing for short filter expressions that cover a breadth of use-cases in lou of SPARQL queries.

Stability: Experimental


This language was created out of a need for constructing quick and easy filters without having to write complex JavaScript expressions. These filters expressions are for testing a single quad/triple at a time, unlike basic graph patterns which might require storing quads in memory until the pattern can be evaluated. Instead, these filter expressions evaluate one at a time against a stream of quads/triples, similar to Triple Patterns.

In the following outline, a few use-case examples are given and followed by an equivalent graph pattern one might use in a SPARQL query.

Prefix Expansion in Regexes

The regex flag c can be used to denote that the pattern should be matched against the Concise Term String representation of the term, using the best prefix available.


Filter by triples where the IRI of the subject starts with the expanded prefix for dbr:, and the predicate is rdf:type and the object dbo:Plant:

/^dbr:/c; a; dbo:Plant

It is equivalent to the following SPARQL graph pattern:

?s a dbo:Plant .
filter(strStarts(str(?s), str(dbr:))

And, Or, Not

The keywords and and but can be used interchangeably to specify that the term must satisfy both conditions. Likewise, or and , can be used interchangeably to specify that the term must satisfy one of the two conditions. The and and but keywords have precedence over the or and , keywords.

Finally, the not and ! keywords can be used interchangeably as a unary operator to negate the condition that follows.


Filter by triples where the subject and object are the same term, while excluding the term dbr:Banana:

$object but not dbr:Banana

It is equivalent to the following SPARQL graph pattern:

?s ?p ?s .
filter(?s != dbr:Banana)


You can specify to match a range of terms based on their type, such as {node}, {named-node}, {blank-node}, {literal}, {simple-literal}, {languaged-literal}, or {datatyped-literal}.

You can also combine tag selectors to specify the union of types, e.g., {named-node, datatyped-literal} will match either a named node or a literal that has a datatype.


Filter by triples where the predicate is dbo:date and the object is a literal, but the literal does not have the datatype xsd:dateTime:

; dbo:date; {literal} but not ^xsd:dateTime

It is equivalent to the following SPARQL graph pattern:

?thing dbo:date ?time

	isLiteral(?time) && datatype(?time) != xsd:dateTime


The union operator | can be used to specify multiple alternative conditions. When used with grouping ( ), it allows you to branch conditionals and without having to combine the preceeding term expressions.


Filter by triples where the subject is dbr:Orange OR the subject is not dbr:Banana and is either (a) of type dbo:Fruit or dbo:Plant, or (b) has an rdfs:label to some literal that has the language tag @en or @de:

not dbr:Banana; (a; dbo:Fruit or dbo:Plant | rdfs:label; @en, @de) | dbr:Orange

It is equivalent to the following SPARQL graph pattern:

			?s a dbo:Fruit
		} union {
			?s a dbo:Plant
		} union {
			?s rdfs:label ?label
				isLiteral(?label) && (
					langMatches(lang(?label), "en")
					|| langMatches(lang(?label), "de")

		filter(?s != dbr:Banana)
	} union {
		dbr:Orange ?p ?o

Quad Filter Expression Grammar

State Production
Expression Subject? (';' Predicate? (';' Object? (';' Graph?)?)?)?
Subject TermExpr
Predicate TermExpr
Object TermExpr
Graph TermExpr
TermExpr TermExprAnd ((',' | 'or') TermExpr)*
TermExprAnd TermExprUnary (('and' | 'but') TermExprAnd)
TermExprUnary ('!' | 'not')? PrimaryExpr
PrimaryExpr Term | Tags | '(' TermExpr ')' | Reference
Term NamedNode | BlankNode | Regex
Tags '{' TagSelector (',' TagSelector)* '}'
TagSelector NODE | 'named' NODE? | 'blank' 's'? NODE? | LITERAL | 'datatype' [sd]? LITERAL? | 'lang' ('s' | 'uage' [sd]?)? LITERAL? | 'simple' 's'? LITERAL
NODE ('-' | '_')? 'node' 's'?
LITERAL ('-' | '_')? 'literal' 's'?
Reference '$s' 'ubject'? | '$p' 'redicate'? | '$o' 'bject'? | '$g' 'raph'?
NamedNode AbsoluteIRI | PrefixedName | TypeAlias
AbsoluteIRI '<' .* '>'
PrefixedName ([^_:@"^`][^:]*)? ':' [^ ]*
TypeAlias 'a'
BlankNode '_' ':' [^ ]*
Literal StringLiteral | Language | Datatype
StringLiteral '"' STRING_CONTENTS '"' (Language | Datatype)
Datatype '^' '^'? NamedNode
Language '@' [a-zA-Z0-9-]+
DefaultGraph '*'