graphy.js

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

Introduction

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.

Example:

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.

Example:

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)

Tags

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.

Example:

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

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

Unions

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.

Example:

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
			filter(
				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'?
Regex '/' REGEX_CONTENTS '/' REGEX_FLAG*
REGEX_FLAG [ic]
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 '*'