This is the reference guide for AllegroGraph 2.2.5. The tutorial can be found here. An introduction to AllegroGraph covering all of its many features at a high-level is in the AllegroGraph Introduction.
Managing AllegroGraph
AllegroGraph provides several utilities to help you manage your triple-stores and AllegroGraph itself. Most of the management operations are carried out automatically but there may be occasions when you will want to take greater control.
The following functions let you set and get properties that control AllegroGraph, find the version you are using and operate on all of the triple-stores that you have open.
name.
extended argument is true, then it also returns the build date.
Search for an open triple-store named by designator. Designator can be one of the following:
- An object of type triple-db
- A pathname which is the directory of a triple-store (cf.
data-directory) - A string which can be coerced into a pathname which is the directory of a triple-store
- A string which is the
nameof an open triple-store.
Note that it is possible that two or more triple-stores are open which have the same naem. In this case find-triple-store will signal an error of type ambiguous-triple-store-designator.
In addition to several special variables that can be let bound to control its behavior dynamically, AllegoGraph has the following properties:
errorp keyword argument to register-namespace. If true and errorp is not supplied , then calling register-namespace with a namespace-prefix that already has a namespace mapping will signal an error. Otherwise the namespace mapping will be changed silently.
format keyword argument to print-triple, print-triples, and triple->string. Defaults to :ntriple.
sys:temporary-directory.
verbose in AllegroGraph functions that have a verbose keyword argument. Examples include load-ntriples, load-xml/rdf and index-all-triples.
prepare-reasoning will output information messages as it runs inferences.
Finally, AllegroGraph periodically runs a variety of background checks to help optimize your triple-stores. These are controlled by the AllegroGraph manager. You can set how often AllegroGraph runs these checks using manager-period.
AllegroGraph-Manager of the AllegroGraph application.
resume-agraph-manager).
pause-agraph-manager).
triple-store management
These functions are used to create, delete, and examine a triple-store. All of a triple-store's data is kept in a single directory whose name it shares. For convenience, many operations act by default on the current triple-store which is kept in a special variable named *db*. The with-triple-store macro makes it easy to call other code with a particular store marked current. There are also several reports that describe the triple-store in detail.
Each triple-store has two parameters that help you to manage its indices automatically: unindexed-triple-count-threshold and unmerged-chunk-count-threshold. The first controls the maximum number of unindexed triples in the store; the second controls the maximum number of index chunks or fragments. When it ships, each triple-store has both of these parameters set to zero (0) which means that no automatic indexing and merging will take place -- everything is left to your control. Here are some of the things that you will want to consider when setting these values.
- Ideally, you would like to have all of your triples indexed into a single index-fragment.
- The lower you set unindexed-triple-count-threshold, the fewer unindexed triples you will have but you will also have more index chunks.
- Each query must examine each index chunk so having too many will slow down query times.
We suggest that you experiment with variations on the parameters. Franz is very open to hearing your feedback on how you would like to manage your triple-store.
One final point is that the automatic indexing and merging is subject to checks by the AllegroGraph manager process (see manager-period elsewhere in this documentation).
db keyword argument default to the value of this variable.
:wait keyword parameter is passed along to close-triple-store. It defaults to nil
Close the triple store, after saving all persistent data to disk as if by sync-triple-store. Close-triple-store has the following keyword arguments:
:db- defaults to the value of *db* and specifies which triple-store to close. *db* is set tonilafter the triple store is closed. A triple-store only needs to be closed once regardless of how many times open-triple-store has been called on it.:if-closed- controls the behavior when thedbis either not open or nil. Ifif-closedis:errorthen an error will be signaled in this situation. If it is:ignore, thenclose-triple-storewill just return without signaling an error. The argument defaults to:ignore.:verboseis true, then a message will be printed to*debug-io*before the triple store is closed.:waitis true thenclose-triple-storewill not return until all of its concurrent activity is complete. This includes synchronizing its data, building indices and running queries. The value of:waitwill be true unless overriden. If it is false, thenclose-triple-storewill return immediately but the triple-store will no longer be available to use. Its actual in-memory structures will not be available to the garbage-collector until all of its background activity is complete and it is finally closed.
Create a new triple store with the given name. This is both the name of the triple-store and its location on disk. It can be the full path to a directory or just a directory name. If it is a simple name, then the directory argument is used to convert it to a complete path.
For example, to create a triple-store named 'animals' in the directory 'c:/datafiles/biology', you could use either
(create-triple-store
"c:/datafiles/biology/animals")
or
(create-triple-store "animals"
:directory "c:/datafiles/biology/")
The directory defaults to the directory component of *default-pathname-defaults*. You cannot use a name containing a directory path and the directory argument simultaneously.
Create-triple-store takes numerous keyword arguments:
:if-exists- controls what to do if the data directory already exists. The default value,:supersede, will cause create-triple-store to delete the old triple store and create a new one;:errorcauses create-triple-store to signal an error; finally, the value:openwill simply open the existing triple store as if you had called open-triple-store.:expected-unique-resouces- sets the initial size of the triple-store. It determines the number of unique names (e.g., resources and literals) that the triple store is expected to hold and defaults to the value of default-expected-unique-resources. The triple-store will grow if this number is exceeded but setting the value initially will provide better performance because no resizing will be required.:with-indices- adds indices to the newly created triple-store. It is equivalent to calling add-index once for each index in the list of indices. It defaults to the value of the AllegroGraph propertystandard-indices.:include-standard-parts- if true, then AllegroGraph will add the following strings to the triple-store at creation time: rdf:type, owl:sameAs, owl:inverseOf, rdfs:subPropertyOf, rdfs:subClassOf, rdfs:range, rdfs:domain, owl:transitiveProperty. The value defaults to the ag-property(:include-standard-parts).
Create-triple-store returns a triple-store object and sets the value of the variable *db* to that object.
:directory parameter to create-triple-store or by using a full pathname as the name argument to create-triple-store.
Delete an existing triple store. Returns t if the deletion was successful and nil if it was not. The :db keyword argument can be either a triple store instance or the name of a triple store. If it is an instance, then the triple store associated with the instance will be deleted. If it is a name, then the triple store of that name in the directory designated by the :directory keyword argument will be deleted. The directory parameter defaults to the directory component of *default-pathname-defaults*.
The :if-does-not-exist keyword argument specifies what to do if the data directory does not exist. The default value, :error, causes delete-triple-store to signal an error. The value :ignore will cause delete-triple-store to do nothing and return nil.
The :if-open keyword argument specifies the behavior if the designated triple store is currently open. The default value, :error, causes delete-triple-store to signal an error. The value :close causes delete-triple-store to close the triple store, as if by close-triple-store and then delete it. If AllegroGraph is unable to close the triple store, an error may still be signaled.
Close any current triple-store and create a new empty one in a temporary directory.
The directory used can be passed in as an optional parameter. If it is not supplied, then it will get its value from (ag-property temporary-directory).
The new triple-store will be bound to *db* and is also returned by make-tutorial-store.
Open an existing triple store (previously created using create-triple-store) with the given name. Name is both the name of the triple-store and its location on disk. It can be the full path to a directory or just a directory name. If it is a simple name, then the directory argument is used to convert it to a complete path.
For example, to open a triple-store named 'animals' in the directory 'c:/datafiles/biology', you could use either
(open-triple-store
"c:/datafiles/biology/animals")
or
(open-triple-store "animals"
:directory "c:/datafiles/biology/")
The directory defaults to the directory component of *default-pathname-defaults*. You cannot use a name containing a directory path and the directory argument simultaneously.
The :if-does-not-exist keyword argument specifies what to do if the data directory does not exist. The default value, :error, causes open-triple-store to signal an error. The value :create will cause open-triple-store to create the triple store as if by a call to create-triple-store.
You can use the :with-indices parameter to add additional indices to the triple-store. (Adding an index multiple times has no effect). This will not remove any indices that already exist (see drop-index and drop-indices if you need to do that).
Returns a triple store object and sets the value of the variable *db* to that object. If the named triple store is already open, open-triple-store returns the same object.
This function has to be called before any inferences are made. It creates internal hashtables to speed up the reasoner. In normal operation, AllegroGraph will call prepare-reasoning as necessary. You can see diagnostic messages by using the parameter verbose which defaults to the value of (ag-property :verbose-prepare-reasoning). You can also force the hashtables to be regenerated using the force parameter. Finally, the show-progress keyword argument can be used to cause prepare-reasoning to print a message for each of the hashtables it builds.
The function prepare-reasoning returns no value.
:db keyword argument specifies the triple store to use, either by name or a triple store object. It defaults to the value of *db*.
Returns true if the triple-store with the given name exists. Name can be the full path to a directory or just a directory name. If it is a simple name, then the directory argument is used to convert it to a complete path.
For example, to verifty the existance of a triple-store named 'animals' in the directory 'c:/datafiles/biology', you could use either
(triple-store-exists-p
"c:/datafiles/biology/animals")
or
(triple-store-exists-p "animals"
:directory "c:/datafiles/biology/")
The directory defaults to the directory component of *default-pathname-defaults*. You cannot use a name containing a directory path and the directory argument simultaneously.
unindexed-triple-count-threshold unindexed triples, an indexing task will be started to index them. If a indexing-host has been added then the task will run on it (see add-indexing-host for details). Otherwise, indexing will run as a background task of the main AllegroGraph process.
Binds both var and db to the triple-store designated by store. The following keyword arguments can also be used:
errorp - controls whether or not
with-triple-storesignals an error if the specified store cannot be found.read-only-p - if specified then with-triple-store will signal an error if the specified triple-store is writable and read-only-p is nil or if the store is read-only and read-only-p is t.
- state - can be :open, :closed or nil. If :open or :closed, an error will be signaled unless the triple-store is in the same state.
This variables controls when changes to the triple store are written to disk. If t, then changes will be written after every call to add-triple. If nil (which is the default), then changes will be written only when the triple store is closed, indexed, or synchonized. A setting is nil is more efficient but can lead to surprises: for example, the results of queries may not contain recently added triples.
Note that functions such as load-ntriples and load-rdf/xml dynamically bind *synchronize-automatically* to nil in their inner loops for efficiency's sake. You may want to use a similar practice in any of your code that adds many triples at once.
Reports
db (which defaults to db unless specified).
stream.
Loading triples in bulk
Triples stored in files using the N-Triples 1 and RDF/XML 2 notations can be loaded into the triple-store with the following functions.
Add triples from source to the triple store.
:db- specifies the triple-store to load into and defaults to the value of db.:default-graphdefaults to nil, which is interpreted asdb's default graph. If supplied, it can be:a string representing a URIref, or a UPI encoding a URIref, which adds the triples in source to a graph named by that URI
the keyword
:source(in which case the source argument will be interned as a URI and the loaded triples added to a graph named by that URI)
The
:verboseargument specifies whether or not progress information is printed to the listener. It defaults to the value of (ag-property:verbose).:always-save-string-literals- determine whether or not to save the strings of a triple's object field when the object can be encoded directly into the triple. If true (the default) then the strings will be saved. If false then only the encoded values will be preserved (this may prevent exact round-trips if data is coerced during the encoding process).source- can be a stream, a pathname to an N-Triples file or a string that can be coerced into a pathname to an N-Triples file.
load-ntriples returns the number of triples added, and the default-graph used, as multiple values.
Add all of the triples from the string to the triple store. The following keyword parameters can be used to control the loading process:
:db- specifies the triple-store to load into and defaults to the value of db.:default-graphdefaults to nil, which is interpreted asdb's default graph. If supplied, it can be:a string representing a URIref, or a UPI encoding a URIref, which adds the triples in source to a graph named by that URI
the keyword
:source(in which case the source argument will be interned as a URI and the loaded triples added to a graph named by that URI)
The
:verboseargument specifies whether or not progress information is printed to the listener. It defaults to the value of (ag-property:verbose).:always-save-string-literals- determine whether or not to save the strings of a triple's object field when the object can be encoded directly into the triple. If true (the default) then the strings will be saved. If false then only the encoded values will be preserved (this may prevent exact round-trips if data is coerced during the encoding process).
load-ntriples-from-string returns the number of triples added, and the default-graph used, as multiple values.
:db keyword argument specifies the triple store to load into and defaults to the value of db. See load-ntriples for more information about the other keyword arguments.
Add triples from the named RDF/XML file to the triple-store. The additional arguments are:
:db- specifies the triple-store into which triples will be loaded; defaults to the value of db.:base-uri- this defaults to the name of the file from which the triples are loaded. It is used to resolve relative URI references during parsing. To use no base-uri, use the empty string "".:default-graphdefaults to nil, which is interpreted asdb's default graph. If supplied, it can be:a string representing a URIref, or a UPI encoding a URIref, which adds the triples in source to a graph named by that URI
the keyword
:source(in which case the source argument will be interned as a URI and the loaded triples added to a graph named by that URI)
use-rapper-p- Ifuse-rapper-pis true, then the RDF/XML file will be piped through the rapper function usingrun-shell-command. Obviously, rapper must be both installed and in your path for this to work. If rapper is not in your path, you can supply it explicity as the value ofuse-rapper-p.
Treat string as an RDF/XML data source and add it to the triple-store. For example:
(load-rdf/xml-from-string
"<?xml version="1.0"?>
<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
xmlns:ex=\"http://example.org/stuff/1.0/\">
<rdf:Description rdf:about=\"http://example.org/item01\">
<ex:prop rdf:parseType=\"Literal\"
xmlns:a=\"http://example.org/a#\"><a:Box required=\"true\">
<a:widget size=\"10\" />
<a:grommit id=\"23\" /></a:Box>
</ex:prop>
</rdf:Description>
</rdf:RDF>
")
See load-rdf/xml for details on the parser and the other arguments to this function.
TriX
RDF in the form of named graphs can also be loaded using load-trix, which understands the TriX format (see http://www.w3.org/2004/03/trix/).
We have implemented a few extensions to TriX to allow it to represent richer data:
- Graphs can be named by
<id>, not just<uri>. (A future revision might also permit literals.) - The default graph can be denoted in two ways: by providing
<default/>as the name for the graph; or by providing a graph URI as an argument toload-trix. - In the interest of generality, the predicate position of a triple is not privileged: it can be a literal or blank node (just like the subject and object), not just a URI.
Saving triples to a file
There are several methods by which you can create a textual representation of your triple-store:
- using print-triples (see below),
- using one of the serialization functions like serialize-rdf/xml or
serialize-rdf-n3 - using the serialization methods in twinql (AllegroGraph's SPARQL sub-system).
The print-triples function provides a simple mechanism to output triples to *standard-output* or a stream. It's easy to build an export function on top of it:
(defun export-triples (triples file)
(with-open-file (output file
:direction :output
:if-does-not-exist :create
:if-exists :error)
(print-triples triples
:limit nil :stream output :format :ntriple)))
The other techniques provide more control over the output format.
:format, which defaults to the value of (ag-property :default-print-triple-format), specifies how the triple should be printed. The value :ntriple specifies that it should be printed in N-Triples syntax. The value :long indicates that the string value of the part should be used. And the value :concise causes it to use a more concise, but possibly ambiguous, human-readable format.
triple-container which can be either a triple store object, a list of triples such as is returned by get-triples-list, or a cursor such as is returned by get-triples. If the keyword argument :limit is supplied, then at most that many triples will be displayed. The :format keyword argument controls how the triples will be displayed, in either :ntriple, :long, or :concise format. It defaults to (ag-property :default-print-triple-format). The stream argument can be used to send output to the stream of your choice. If left unspecified, then output will go to standard-output.
Write from, which should be a triple store, a list, or a cursor, to to, which should be a stream, file path, t (print to *standard-output*), or nil (return a string).
If from is a triple-store or a list of triples, and prepare-namespaces-p is t, it is first traversed to build a hash of namespaces to prefixes for all properties in the store. The value of db.agraph::*namespaces* is used as a seed.
If you can ensure that every property used in the triple-store has a defined prefix, you can pass nil for prepare-namespaces-p to gain a speed improvement from omitting this phase.
If error-on-invalid-p is t, the serializer will throw an error if it encounters a type or predicate that it cannot abbreviate for RDF/XML.
If a namespace prefix table is built, it will be returned as the second value.
If from is a cursor, it cannot be traversed multiple times, so prepare-namespaces-p is ignored. If a property is encountered that cannot be abbreviated with the current available prefixes, an error will be signaled, unless error-on-invalid-p is nil. You should be aware of this before using this serializer: serializing the output of a cursor can fail if you do not first prepare namespace mappings, or specify that invalid output is acceptable.
if-exists and if-does-not-exist are arguments to the Common Lisp open function which apply when to is a filename.
If memoize-abbrev-lookups-p is t, a upi-hash-table is built to store the mappings between resources in the store and string abbreviations. This hash-table will contain as many entries as there are types and properties in the data to be serialized. For some datasets disabling this caching will yield a significant reduction in space usage in exchange for a possible loss of speed.
If indent is non-nil, then it specifies the initial indentation of elements.
If nestp is t, then (subject to the order of triples in the triple store) some nesting of RDF/XML elements will be applied. nestp of nil will cause a flat tree to be produced, where each resource is its own top-level element.
If output-types-p is t, then additional queries will be performed for each resource to decorate the RDF/XML with types. If nil, then rdf:type elements alone will be used.
Please note that the RDF/XML serializer is not guaranteed to work correctly with value-encoded literals.
Serialize source according to exchange-of-named-rdf-graphs. Serialization will probably open at least as many files as there are graphs in the source.
Returns the manifest path and the number of graphs saved.
If single-stream-p only a single file is open at any one time. This is slower, but guaranteed not to fail with large numbers of graphs.
SPARQL support
AllegroGraph includes twinql, an implementation of the powerful SPARQL query language. You can learn more about twinql and SPARQL in the twinql reference and tutorial.
parse-sparql takes a string and parses it into an s-expression format. A parse error will result in a sparql-parse-error being raised.
This function is useful for three reasons: validation and inspection of queries, manual manipulation of query expressions without text processing, and performing parsing at a more convenient time than during query execution.
You do not need an open triple store in order to parse a query.
default-base and default-prefixes allow you to provide BASE and PREFIX arguments to the parser without inserting them textually into the query.
default-base should be nil or a string, and default-prefixes can either be a hash-table (string prefix to string expansion) or a list similar to db.agraph:*standard-namespaces*.
parse-sparql returns the s-expression representation of the query string.
run-sparql takes a SPARQL query as input and returns bindings or new triples as output.
SELECT and ASK query results will be presented in results-format; the RDF output of DESCRIBE and CONSTRUCT will be serialized according to rdf-format. If the format is programmatic, any results will be returned as the first value, and nothing will be printed on output-stream.
querycan be a string, which will be parsed byparse-sparql, or an s-expression as produced byparse-sparql. If you expect to run a query many times, you can avoid some parser overhead by parsing your query once and callingrun-sparqlwith the parsed representation.If
queryis a string, thendefault-baseanddefault-prefixesare provided toparse-sparqlto use when parsing the query. See the documentation for that function for details. Parser errors can be signaled withinparse-sparql, and will be propagated onwards byrun-sparql.Results or new triples will be serialized to
output-stream. If a programmatic format is chosen for output, the stream is irrelevant. An error will be signaled ifoutput-streamis not astream,t, ornil.If
limit,offset,from, orfrom-namedare provided, they override the corresponding values specified in the query string itself. AsFROMandFROM NAMEDtogether define a dataset, and the SPARQL Protocol specification states that a dataset specified in the protocol (in this case, the programmatic API) overrides that in the query, if eitherfromorfrom-namedare non-nilthen any dataset specifications in the query are ignored. You can specify that the contents of the query are to be partially overridden by providingtas the value of one of these arguments. This is interpreted as 'use the contents of the query'.fromandfrom-namedshould be lists of URIs.default-dataset-behaviorcontrols how the query engine builds the dataset environment ifFROMorFROM NAMEDare not provided. Valid options are:all(ignore graphs; include all triples) and:default(include only the triple store's default graph).with-variablesshould be an alist of symbols and values. Before the query is executed, the variables named after symbols will be bound to the provided values. This allows you to use variables in your query which are externally imposed, or generated by other queries. The format expected bywith-variablesis the same as that used for each element of the list returned by the:alistsresults-format.db(*db*by default) specifies the triple store against which queries should run.If
verbosepis non-nil, status information is written to*sparql-log-stream*(*standard-output*by default).
Three additional extensions are provided for your use.
If
extendedpis true (or*use-extended-sparql-verbs-p*is true, and the argument omitted) some additional SPARQL verbs become available.SUM,AVERAGE,MEDIAN,STATS,CORRELATION, andCOUNTcan all be used in place ofSELECT. These verbs are still experimental and undocumented.If
memoizepis true (or*build-filter-memoizes-p*is true, and the argument omitted) calls to SPARQL query functions (such asSTR,fn:matches, and extension functions) will be memoized for the duration of the query. For most queries this will yield speed increases whenFILTERorORDER BYare used, at the cost of additional memory consumption (and consequent GC activity). For some queries (those where repetition of function calls is rare) the cost of memoization will outweigh the benefits. In large queries which call SPARQL functions on many values, the size of the memos can grow large.
Memoization also requires that your extension functions do not depend on side-effects. The standard library is correct in this regard.
- You can achieve substantial speed increases by sharing your memos between queries. Create a normal
eqlhash-table with(make-hash-table), passing it as the value of thememosargument torun-sparql. This hash-table will gradually fill with memos for each used query function.
If you wish to globally enable memoization, set the variables as follows:
(progn
(setf *build-filter-memoizes-p* t)
(setf *sparql-sop-memos* (make-hash-table)))
Be aware that the size of *sparql-sop-memos* could grow very large indeed. You might consider using a weak hash-table, or periodically discarding the contents of the hash-table.
load-functionis a function with signature(uri db &optional type)ornil. If it is a function, it is called once for eachFROMandFROM NAMEDparameter making up the dataset of the query. The execution of the query commences once each parameter has been processed. Thetypeargument is either:fromor:from-named, and theuriargument is a part (ordinarily afuture-part) naming a URI. The default value is taken from*dataset-load-function*. You can use this hook function to implement loading of RDF before the query is executed.
The values returned by run-sparql are dependent on the verb used. The first value is typically disregarded in the case of results being written to output-stream. If output-stream is nil, the first value will be the results collected into a string (similar to the way in which cl:format operates).
The second value is the query verb: one of :select, :ask, :construct, or :describe. Other values are possible in extended mode.
The third value, for SELECT queries only, is a list of variables. This list can be used as a key into the values returned by the :arrays and lists results formats, amongst other things.
Individual results formats are permitted to return additional values.
format argument. See the documentation for run-sparql for more information.
Run the provided query, using the results to construct a new graph. The new graph is either returned or serialized onto output-stream as specified by the format argument. construct-pattern must be a list of triple patterns. query-pattern is used as input to run-sparql-select.
See the documentation for run-sparql for more information.
UPI coercion depends on the current value of db!
Run the provided query, using the results to construct a new graph. The new graph is either returned or serialized onto output-stream as specified by the format argument. targets is a list of resources to describe. query is used as input to run-sparql-select to yield further resources to describe.
See the documentation for run-sparql for more information.
Run the provided query, serializing the results as specified by the format argument. :distinct can be t or :distinct, meaning full DISTINCT processing, or :reduced, which optionally discards duplicates.
See the documentation for run-sparql for more information.
Return a list of alists, each of which contains the values for variables in order. If variables is not provided, you can find the variables as the second return value.
Return a list of lists, each of which contains the values for variables in order. If variables is not provided, you can find the variables as the second return value.
Manipulating triples
You can add triples to a triple-store programatically with the function add-triple. The three required arguments, representing the subject, predicate, and object of the triple to be added can be expressed either as strings in the N-Triples syntax for URI references and literals or as UPIs such as are returned by the functions intern-resource, intern-literal, intern-typed-literal, and new-blank-node.
The functions subject, predicate, object, and graph provide access to the part UPIs of triples returned by the cursor functions like row and next-row and collected by get-triples-list.
Add a new triple to the triple-store with the given subject, predicate and object and graph, specified either as UPIs or strings in N-Triples format. The :db keyword argument specifies the triple store to which the triple will be added and defaults to the value of *db*. Returns the numeric id of the new triple.
Note that duplicate triples can be added to a triple-store but indices will only refer to the same triple once.
get-triples since the cursor reuses the triple datastructure for efficiency reasons.
Marks the triple whose id is id as deleted.
See also undelete-triple and undeleted-triple-p.
The :db keyword argument specifies the triple store in which the triple should be marked as deleted.
Delete triples matching the given subject, predicate, object, and graph, specified either as part IDs, strings in N-Triples format, or the wildcard nil. Returns the number of triples deleted.
The :db keyword argument specifies the triple store to query, defaulting to the value of *db*.
Returns a boolean indicated whether the triple whose ID is id is deleted.
The :db keyword argument specifies the triple store in which to check.
triple-id is id and return it. The keyword argument db can be used to specify the triple-store in which to search. It defaults to the current triple-store, *db*. Get-triple-by-id allocates a new triple (using make-triple. You can prevent this by passing in your own triple using the keyword argument :triple. The data in the triple you pass in will by overwritten.
Sets and gets the graph UPI of a triple.
In addition to being returned, the optional upi argument will be filled in with the graph's UPI. If not passed in, a new UPI will be created.
Sets and gets the object UPI of a triple.
In addition to being returned, the optional upi argument will be filled in with the object's UPI. If not passed in, a new UPI will be created.
part which can be either a UPI or a future-part.
part (which can be a UPI or a future-part). The :format keyword argument controls the format and can be one of :ntriple, :long, or :concise, as with the :format argument to print-triple. The default is the value of (ag-property :default-print-triple-format).
part. Part can be UPI or a future-part.
Sets and gets the predicate UPI of a triple.
In addition to being returned, the optional upi argument will be filled in with the predicate's UPI. If not passed in, a new UPI will be created.
Sets and gets the subject UPI of a triple.
In addition to being returned, the optional upi argument will be filled in with the subject's UPI. If not passed in, a new UPI will be created.
triple1 and triple2 and returns true if they have the same contents and false otherwise.
Unsets the deleted flag from the triple whose id is id.
The :db keyword argument specifies the triple store in which the triple should be marked as undeleted.
Returns the UPI associated with the future-part future-part.
If the future-part uses namespaces, then calling upi will resolve the namespace mapping. An error will be signaled if upi is called and there is no namespace mapping defined. You can use the errorp keyword parameter to disable the error and return nil instead.
Decodes UPI and returns the value, the type-code and any extra information as multiple values. These three things can be interpreted as follows:
- value - a string representing the contents of the UPI
- type-code - an integer corresponding to one of the defined UPI types (see supported-types for more information). You can use type-code->type-name to see the English name of the type.
- extra - Some encoded UPIs contain additional information which will be placed in
extraif it is there. Examples include the language code or datatype of a literal.
Examples:
> (upi->value (value->upi 22 :byte))
==> 22
==> 18
==> nil
> (upi->value (upi (literal "hello" :language "en")))
==> "hello"
==> 3
==> "en"
Triple Parts: Resources, Literals, and Blank nodes.
Each triple has five parts (!), a subject, a predicate, an object, a graph and a (unique, AllegroGraph assigned) ID. In RDF, the subject must be a "resource", i.e., a URI or a blank node. The predicate must be a URI. The object may be a URI, a blank node or a "literal". Literals are represented as strings with an optional type indicated by URI or with a (human) language tag such as en or jp.
3 ; "Blank nodes" are anonymous parts whose identity is only meaningful within a given triple-store.
Resources and literals can be denoted with plain Lisp strings in the syntax used in N-Triples files. However this isn't entirely convenient since the N-Triples syntax for literals requires quotation marks which then need to be escaped when writing a Lisp string. For instance the literal whose value is "foo" must be written in N-Triples syntax as "\"foo\"". Similarly -- though not quite as irksome -- URIs must be written enclosed in angle brackets. The string "http://www.franz.com/simple#lastName", passed as an argument to add-triple will be interpreted as a literal, not as the resource indicated by the URI. To refer to the resource in N-Triples syntax you must write "<http://www.franz.com/simple#lastName> ". Finally, literals with datatypes or language codes are even more cumbersome to write as strings, requiring both escaped quotation marks and other syntax.
To ease the pain of producing correctly formatted N-Triples strings we provide two functions resource and literal that take care of building a syntactically correct N-Triples string. (The ! reader macro, discussed below, can also be used to produce syntactically correct N-Triples strings.) For efficiency, these are
Create a new future-part with the provided values.
If provide, the language argument should be a valid RDF language tag.
If provided, the datatype can be a string or future-part specifying a resource. An overview of RDF datatypes can be found in the W3C's RDF concepts guide.
Only one of datatype and language can be used at any one time.
Some examples (we will describe and explain the ! notation below):
(resource "http://www.franz.com/") =>
!<http://www.franz.com/>
(literal "Peter") => !"Peter"
(literal "10" :datatype
"http://www.example.com/datatypes#Integer") =>
!"10"^^<http://www.example.com/datatypes#Integer>
(literal "Lisp" :language "EN") => !"Lisp"@en
Another issue with using Lisp strings to denote literals and resources is that the strings must, at some point, be translated to the UPIs used internally by the triple-store. This means that if you are going to add a large number of triples containing the same resource or literal and you pass the resource or literal value as a string, add-triple will have to repeatedly convert the string into its UPI.
The functions intern-resource, intern-literal, intern-typed-literal can be used to compute the UPI of a resource, or literal which can then be passed to add-triple, saving the cost of having to compute the UPI each time add-triple is called. Similarly the function new-blank-node can be used to the UPI of a new anonymous node for use as the subject or object of a triple.
Returns true if upi is a blank node and nil otherwise. For example:
> (blank-node-p (new-blank-node))
t
> (blank-node-p (literal "hello"))
nil
db and return the UPI. If a upi is not passed in with the :upi parameter, then a new UPI structure will be created.
This convenience macro binds one or more variables to new blank nodes within the body of the form. For example:
(with-blank-nodes (b1 b2)
(add-triple b1 !rdf:type !ex:Person)
(add-triple b1 !ex:firstName "Gary")
(add-triple b2 !rdf:type !ex:Dog)
(add-triple b2 !ex:firstName "Abbey")
(add-triple b2 !ex:petOf b1))
The following function demonstrates the use of these functions. First we use intern-resource to avoid repeatedly translating the URIs used as predicates into numeric IDs and then use new-blank-node to create a blank node representing each employee and intern-literal and intern-typed-literal to translate the strings in the list employee-data into IDs. (We could also use literal to translate the strings to N-Triples strings which would then be parsed and interned by add-triple but this is more efficient.)
(defun add-employees (company employee-data)
(let ((first-name (intern-resource
"http://www.franz.com/simple#firstName"))
(last-name (intern-resource
"http://www.franz.com/simple#lastName"))
(salary (intern-resource
"http://www.franz.com/simple#salary"))
(employs (intern-resource
"http://www.franz.com/simple#employs"))
(employed-by (intern-resource
"http://www.franz.com/simple#employed-by")))
(loop for (first last sal) in employee-data do
(let ((employee (new-blank-node)))
(add-triple company employs employee)
(add-triple employee employed-by company)
(add-triple employee first-name (intern-literal first))
(add-triple employee last-name (intern-literal last))
(add-triple employee salary
(intern-typed-literal
sal
"http://www.franz.com/types#dollars"))))))
Finally, you can compare triples and UPIs using
triple1 and triple2 and returns true if they have the same contents and false otherwise.
thing appears to be a UPI. Recall that every UPI is a octet array 12 bytes in length but not every length 12 octet array is a UPI. It is possible, therefore, that upip will return true even if thing is not a UPI.
type of a UPI. The type is a one-byte tag that describes how the rest of the bytes in the UPI should be interpreted. Some UPIs are hashed and their representation is stored in a string-table. Other UPIs encode their representation directly (see upi->value and value->upi for additional details).
Datatype and predicate mapping
Most triple-stores work internally only with strings. AllegroGraph, however, can store a wide range of datatypes directly in its triples. This ability not only allows for huge reductions in triple-store size but also lets AllegroGraph execute range queries remarkably quickly. Use the supported-types function to see a list of datatypes that AllegroGraph can encode directly. The datatypes are specified as keywords or integers (with the integers being used internally). You can translate in either direction using type-code->type-name and type-name->type-code. You can add encoded-triples (i.e., triples some of whose parts are encoded UPIs rather than references to strings) directly using add-triple or by setting up mappings between particular predicates or specific datatypes and then using one of the bulk loading functions. In the former case, you use value->upi and in the later, you use datatype-mappings and predicate-mappings.
For example, we can add a triple that directly points to another by using the :triple-id AllegroGraph datatype. This provides a simple and light-weight reification mechanism but note that it is outside the boundaries of RDF. Here we add one triple that describes Gary's birthdate and another that says the first is wrong.
> (let ((new-id (add-triple !o:gary
!o:birthdate
(value->upi "1924-03-13" :date))))
> (add-triple !o:data !o:incorrect (value->upi new-id :triple-id)))
As a second example, here is how to specify that the datatype xsd:double maps to an AllegroGraph :double-float and the predicate http://www.example.com/predicate#age maps to an :unsigned-byte
> (setf (datatype-mapping "<http://www.w3.org/2001/XMLSchema#double>")
:double-float)
:double-float
> (setf (predicate-mapping "<http://www.example.com/predicate#age>")
:unsigned-byte)
:unsigned-byte
Now when you load an RDF file, AllegroGraph will example each triples to see if it satisfies the mappings. When it does, then an encoded-triple will be added to the triple-store. Depending on your needs, you can even tell AllegroGraph to only load encoded-triples and not worry about strings at all. This can provide tremendous spaces savings and also gives you the benefit of range queries.
Returns the type encoding for string. String should be XML Schema type designator. For example:
> (datatype-mapping "http://www.w3.org/2001/XMSchema#unsignedByte")
:unsigned-byte
see (setf datatype-mapping) for more information.
Returns the type encoding for string. String should be the uriref of a property. For example:
> (predicate-mapping !<http://www.example.org/property/height>)
:double-float
See (setf predicate-mapping) for more information.
Returns a list of type names that can be used in value->upi to encode a string into an encoded UPI. To see the corresponding type code for a name, use the type-name->type-code function.
See the section on type mapping.
code. See type-name->type-code and supported-types for more details. The numbers can come from the type-names returned by supported-types or can correspond to RDF node types like blank nodes, resources and literals. The function returns nil if the code does not correspond to any type.
Returns the type code associated with the name. See type-code->type-name and supported-types. The name can be one of the supported-types or one of:
- :blank-node
- :resource
- :literal
- :literal-language
- :literal-short
- :literal-typed
The function returns nil if there is no type-code corresponding to name.