0.0.1 • Published 6 years ago

gtar v0.0.1

Weekly downloads
3
License
ISC
Repository
github
Last release
6 years ago

GTAR -- the Graph Traversal API for RDF

This document is an open initiative to define a standard API for querying RDF in a graph-traversal paradigm.

Contents

ct_string -- The Concise Term String

A Turtle-like string syntax for expressing an RDF term in a concise format.

When dealing with RDF Terms in program memory, there are many advantages to using a 'plain' UTF*-encoded string rather than a more complex data structure. While many RDF toolkits already use strings internally, they typically use a minor variation of the N-Triples syntax. However, this format aims to be both user-friendly and serialization-ready by taking advantage of the fact that the program environment handles the boundaries of the string, allowing the syntax to use less characters for delimiting, to not worry about escaping, and to facilitate common procedures such as determining the type of an RDF Term.

For example, the first character of a string always tells exactly what type of Term it is:

Notice:

  • the content of a Literal does not need to be escaped
  • the 'suffix' part of prefixed names may contain any unescaped character, except for ", which will expand to that exact string as an IRI; e.g., 'dbr:9/11_Memorial_(Arizona)'

No Escaping Needed Since only one term can be expressed in a string, the syntax does not need to have delimiters for the start or end of certain sequences. For example, a plain RDF literal can be expressed like so: '"Hello World!'. Here, the double quote indicates that this is a plain literal, and that the content follows (until the end of the string). If you were to add quotes before and after the same literal, it would look like this: '""Hello World!"'. If you need single quotes in the string, it is recommended that you use JavaScript's template literals: `"Hey y'all!`.

Grammar

StateProduction
TermNamedNode | BlankNode | Literal
NamedNode([^_:@"^][^:"]*)? ':' [^"]*
BlankNode'_' ':' .*
LiteralPlainLiteral | DatatypedLiteral | LanguagedLiteral
PlainLiteral'"' .*
DatatypedLiteral'^' NamedNode PlainLiteral
LanguagedLiteral'@' [a-zA-Z0-9-]+ PlainLiteral

ct_string#NamedNode

Production: '>' IRI | PREFIX ':' SUFFIX

ct_string#BlankNode

Production: '_' LABEL

ct_string#LaguagedLiteral

Production: '@' LANG-TAG '"' VALUE LANG-TAG -- a BCP-47 string

ct_string#DatatypedLiteral

Production: '^' NAMED_NODE '"' VALUE NAMED_NODE -- a NamedNode CT_String


API Reference

A query starts by forming a chain of calls on the Store object.

class Store

A class that represents a handle to an RDF dataset that acts as the entry-point to query-building.

Methods:

  • .pattern() -- Start building a graph pattern query.

class Pattern

abstract class Fix

A position 'fix' within the graph pattern. It can match against a subject, a predicate, an object, or a set made up of one of those. Graph patterns are essentially built by chaining together a series of fixes.

Methods:

  • .mark(label: string) -- marks this fix with the given label so that once a match is found, the corresponding Term will be accessible in the Result object under the key: label
    • returns this
  • .data(pluginAlias: string, handler: callback(DataPluginHandler))
    • returns this
  • .filter(filterFunction: callback(Term)) -- filters the set of Terms that the current fix will match. For the best performance, use data ranges whenever possible to limit the result set using arbitrary, indexable criteria.
  • .join(name: string) -- produces a cyclic graph pattern by joining this fix with all other fixes where .join() was also called with the given name. Works most efficiently when joining subject-subject, subject-object, object-object or predicate-predicate. For all others (e.g., subject-predicate, subject-datatype, and so on..), the internal ids do not correspond and so the fixes are matched by string comparison of their corresponding dictionary entries.
    • returns this
  • .pipe(forward: callback(ClosedPattern)) -- exits the current pattern by calling .exit(), and then calls the given forward. Useful for intersecting two or more patterns when you need to perform a join that is not the regular {subject-subject, subject-object, or object-object} such as casting a subject into a predicate or a subject into a datatype as with TBOX queries.
    • returns result of call to forward()
    • example:
      // select ?s ?p ?o {
      //    ?p rdf:type owl:SymmetricProperty .
      //    ?s ?p ?o .
      // }
      k_graph.pattern()
         .objectNode('owl:SymmetricProperty').edgeIn('rdf:type')
         .subjects().mark('symm')
         .pipe(k_res => k_graph.pattern()
            .subects().mark('s')
            .edgesOut(k_res.distinct('symm')).mark('p')
            .objects().mark('o')
         .exit());
  • .exit() -- terminate the pattern at the current fix

EmptyPattern implements NormalEdgeFix, InverseEdgeFix

Represents the state of a PatternBuilder when no fixes have been made yet. The first fix must be either a subject, object or hop. Methods:

... those inherited from NormalEdgeFix ... and those inherited from InverseEdgeFix SubjectFix extends SeekableFix Methods:

.edgeOut(predicate:tt_string) -- fixes on the given predicate in the normal direction

.edgesOut(predicates: Array{tt_string} |TermSet) -- fixes on any matching predicates in the normal direction

.edgesOut() -- fixes on all predicates in the normal direction

returns a NormalEdgeFix .forkOut(tt_router: hash{predicate:tt_string=> edge: callback(NormalEdgeFix)})

Forks the graph pattern so that it can traverse down multiple paths. Forking does not change the current fix, so chaining a call after it will apply to this. returns this example: .subject('dbr:Banana') .forkOut({ 'rdf:type': (e) => e.objectNodes().save('type'), 'rdfs:label': (e) => e.literals().save('name'), }) SeekableFix A fix that can be the starting point of an arbitrary length path. Methods:

.seek(to:SeekTargetOptions) -- will attempt to find all paths from the current fix that meet the criteria given by SeekOptions SeekTargetOptions extends SeekOptions Keys / Values:

... exactly one of the key / value pairs as required in SeekOptions The following are optional: .min => integer -- the minimum number of predicates to cross .max => integer -- the maximum number of predicates to cross .limit => integer -- prevent exploring any deeper once the given number of paths have been satisfied .pattern => Array{tp_string} -- a pattern that defines which predicates and in which directions to traverse triples in example: { subject: sf => sf.cross('rdfs:label').literal('Banana'), // out rdfs:label, then in rdfs:label, then out rdf:type at least once pattern: 'rdfs:label', '^rdfs:label', 'rdf:type+', } HopFix implements SubjectFix, ObjectFix Methods:

... those inherited from SubjectFix ... and those inherited from ObjectFix NormalEdgeFix extends Fix Methods:

.hop(hopNode:tt_string) -- fixes on the given hopNode

.hops(hopNodes: Array{tt_string}) -- fixes on any matching hopNodes

.hops() -- fixes on all hops

returns a HopFix .object(objectCap:tt_string) -- fixes on the given objectCap, which can be either a node or a literal

.objects(objectCaps: Array{tt_string}) -- fixes on objectCaps, which can contain a mix of nodes and literals

.objects() -- fixes on all objects

returns an ObjectFix .objectNode(objectNode:tt_string) -- fixes on the given objectNode

.objectNodes(objectNodes: Array{tt_string}) -- fixes on any matching objectNodes

.objectNodes() -- fixes on all objects

returns an ObjectFix .literal(objectLiteral:tt_string) -- fixes on the given objectLiteral

.literals(objectLiterals:tt_string) -- fixes on any matching objectLiterals

.literals() -- fixes on all literals

returns an ObjectFix .leaf(leafCap:tt_string) -- fixes on the given leafCap, which can be either a node or a literal

.leafs(leafCaps: Array{tt_string}) -- fixes on leafCaps, which can contain a mix of nodes and literals

.leafs() -- fixes on all leafs (objects that do not appear as subjects, including literals)

returns an ObjectFix .leafNode(leafNode:tt_string) -- fixes on the given leafNode

.leafNode(leafNodes: Array{tt_string}) -- fixes on any matching leafNodes

.leafNodes() -- fixes on all leaf nodes (object nodes that do not appear as subects)

returns an ObjectFix InverseEdgeFix extends Fix Methods:

.hop(hopNode:tt_string) -- fixes on the given hopNode

.hops(hopNodes: Array{tt_string}) -- fixes on any matching hopNodes

.hops() -- fixes on all hops

returns a HopFix .subject(subjectNode:tt_string) -- fixes on the given subjectNode

.subjects(subjectNodes: Array{tt_string}) -- fixes on any matching subjectNodes

.subjects() -- fixes on all subjects

returns a SubjectFix .root(rootNode:tt_string) -- fixes on the given rootNode

.roots(rootNodes: Array{tt_string}) -- fixes on any matching rootNodes

.roots() -- fixes on all roots

returns a SubjectFix ObjectFix extends SeekableFix Methods:

.edgeIn(predicate:tt_string) -- fixes on the given predicate in the inverse direction

.edgesIn() -- fixes on all predicates in the inverse direction

.edgesIn(predicates: Array{tt_string}) -- fixes on any matching predicates in the inverse direction

returns an InverseEdgeFix .forkIn(t3_router: hash{predicate:tt_string=> edge: callback(InverseEdgeFix)})

Forks the graph pattern so that it can traverse down multiple paths. Forking does not change the current fix, so chaining a call after it will apply to this. returns this example: .subject('dbr:Banana') .fork({ 'rdf:type': (e) => e.objectNodes().mark('type'), 'rdfs:label': (e) => e.literals().mark('name'), }) QueryableGraph Methods:

.pattern() -- enters a new graph pattern returns an EmptyPattern .path() -- enters a new path returns an EmptyPath EmptyPath Methods:

.from(source:SeekTargetOptions) -- sets the starting point of a path given by source returns an OpenPath OpenPath Methods:

.to(dest:SeekOptions) -- adds a checkpoint to the end of the curent path given by dest returns a new OpenPath (i.e., not this) see example .exit() -- exits the current path returns a ClosedPath ClosedPath Methods:

. SeekOptions Keys / Values:

Exactly one of the following key / value pairs is required: .subject => subjectNode:tt_string -- seek to the given subjectNode .object => objectCap:tt_string -- seek to the given objectCap, which may be either a node or a literal .hop => hopNode:tt_string -- seek to the given hopNode .node => someNode:tt_string -- seek to someNode which may be either a subject, object or both. This is useful when the direction of the last leg of the path is not known. .subject => callback(find:SubjectFix) -- seek to some subject given by find .object => callback(find:ObjectFix) -- seek to some object given by find .hop => callback(find:HopFix) -- seek to some hop given by find