sparql expecting one of "where", "using" - sparql

I am trying to do a simple insert query in the web interface of Fuseki server. I have set the endpoint to /update (instead of the default /sparql).
I have the following query from https://www.w3.org/Submission/SPARQL-Update/:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
INSERT { <http://example/egbook3> dc:title "This is an example title" }
This query gets translated to:
http://localhost:3033/dataset.html#query=PREFIX+dc%3A+%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%3E%0AINSERT+%7B+%3Chttp%3A%2F%2Fexample%2Fegbook3%3E+dc%3Atitle++%22This+is+an+example+title%22+%7D%0A
or
curl http://localhost:3033/infUpdate/update -X POST --data 'update=PREFIX+dc%3A+%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%3E%0AINSERT+%7B+%3Chttp%3A%2F%2Fexample%2Fegbook3%3E+dc%3Atitle++%22This+is+an+example+title%22+%7D%0A' -H 'Accept: text/plain,*/*;q=0.9' as visible using the Share your query button.
The query returns the following error:
Error 400: Encountered "<EOF>" at line 2, column 73.
Was expecting one of:
"where" ...
"using" ...
Fuseki - version 2.4.0 (Build date: 2016-05-10T11:59:39+0000)
The error occurs both in the web interface and with curl. What could be the problem here? SELECT queries work without problems. Loading triples from a file through the web interface upload form also works. Additional question: the normal post request uses query= and the curl version uses update=, why is this different?

The document you're referencing is the 2008 SPARQL Update submission, not the actual 2013 SPARQL 1.1 recommendation. The recommendation is the actual standard, the submission is not.
An update (insert or delete) isn't a query (select, ask, construct), and the syntax for the two kinds of query aren't necessarily the same. You note (correctly) that WHERE is optional in a select query, but that doesn't mean that it's optional in an insert. There are two forms of insert. There's INSERT DATA which has the syntax:
INSERT DATA QuadData
and there's DELETE/INSERT which has the syntax:
( WITH IRIref )?
( ( DeleteClause InsertClause? ) | InsertClause )
( USING ( NAMED )? IRIref )*
WHERE GroupGraphPattern
DeleteClause ::= DELETE QuadPattern
InsertClause ::= INSERT QuadPattern
So if you're using INSERT { … }, then that's the InsertClause of a DELETE/INSERT form, and you need to follow it with WHERE …. Since you're using static data, you should probably just use the INSERT DATA form:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
INSERT DATA { <http://example/egbook3> dc:title "This is an example title" }

Related

GraphDB: use similarity search with embedded repository

I have been using GraphDB's (version 9.2) similarity search from the workbench. Now I also want to use this feature for an embedded repository using graphdb-free-runtime 9.2.1. However I have no clue how this feature can be used from the APIs provided by the runtime. My questions are:
In http://graphdb.ontotext.com/documentation/standard/semantic-similarity-searches.html it is mentioned that similarity search is a plugin. However I could not find any such plugin within the runtime. Do I have to load it from some external resource? Where?
Is there any documentation or example how to create a similarity index programmatically?
Would it be an option to run the workbench as some kind of server and access the similarity search via REST API? However the REST API documentation at http://graphdb.ontotext.com/documentation/9.0/free/using-the-workbench-rest-api.html does not mention any API for similarity searches. Am I missing something?
Any hints or pointers are welcome.
You could add similarity plugin runtime, setting following "graphdb.extra.plugins" property to directory where similarity-plugin (you could find such into GDB instance -> dist/lib/plugins) is located , or:
-Dgraphdb.extra.plugins=directory
System.setProperty("graphdb.extra.plugins", "directory");
You may create index programmatically using SPARQL or:
to create similarity text index "allNews" execute following update:
PREFIX : <http://www.ontotext.com/graphdb/similarity/>
PREFIX inst: <http://www.ontotext.com/graphdb/similarity/instance/>
PREFIX pred: <http://www.ontotext.com/graphdb/similarity/psi/>
insert {
inst:allNews :createIndex "-termweight idf" ;
:analyzer "org.apache.lucene.analysis.en.EnglishAnalyzer" ;
:documentID ?documentID .
?documentID :documentText ?documentText .
} where {
SELECT ?documentID ?documentText {
?documentID ?p ?documentText .
filter(isLiteral(?documentText))
}
}
to delete index "allNews" execute following update:
PREFIX :<http://www.ontotext.com/graphdb/similarity/>
PREFIX inst:<http://www.ontotext.com/graphdb/similarity/instance/>
insert { inst:allNews :deleteIndex '' } where {}
to rebuild index "allNews":
PREFIX :<http://www.ontotext.com/graphdb/similarity/>
PREFIX inst:<http://www.ontotext.com/graphdb/similarity/instance/>
insert { inst:allNews :rebuildIndex '' } where {}
followed by the create query!
to list all created indexes, execute following query:
PREFIX :<http://www.ontotext.com/graphdb/similarity/>
PREFIX inst:<http://www.ontotext.com/graphdb/similarity/instance/>
select ?index ?status ?type
where {
?index :status ?status .
?index :type ?type .
}

How to Sparql INSERT in TopBraid Composer?

I'm trying to insert new classes by using Sparql in TopBraid Composer (ME 5.5.2). My simple ontology looks like this:
Then I wrote a Sparql query to insert Berry as a subclass of Fruit:
PREFIX ft: <http://www.semanticweb.org/ontologies/2018/7/fruit#>
PREFIX rdfs: <ttp://www.w3.org/2000/01/rdf-schema#>
INSERT
{ft:Berry rdfs:subClassOf ft:Fruit}
But an error message appeared, saying Encountered "insert". Was expecting one of: "base, "select", ...
A similar post: Sparql insert data not working says that Sparql Query is a different language from Sparql Update. Some other post says that Sparql Update is not supported in Protege but is supported in Composer (for which reason I downloaded Composer). I also checked the Composer manual: https://www.topquadrant.com/docs/TBC-Getting-Started-Guide52.pdf, which mentions Sparql Update but doesn't say much.
My question then is, is it possible to insert classes and axioms in TopBraid? If so, how? My end goal is that the inserted classes will appear in the hierarchical view, and their inserted class definitions can be seen on the side as well. If Composer can't do this, what other tools/workflows can I use?
Sorry for such a newbie question. Any help is appreciated.
There are two forms of INSERT in SPARQL 1.1 Update:
INSERT DATA
INSERT
You are mixing them up.
The following works for me in TBC 5.5.2 Free Edition against the kennedys.ttl example:
INSERT DATA
{ kennedys:UralStateUniversity a kennedys:College }
Being an unknown URI, the subject is underlined in query editor, but just press the "Execute SPARQL" button.
Update
In your particular case, you should say something like
INSERT DATA
{ ft:Berry rdfs:subClassOf ft:Fruit; a owl:Class }
Please note that owl:Class is used. TBC considers instances of rdfs:Class as "system classes", their icons are brown, not yellow.

SPARUL query to drop most graphs, using Jena API

I am trying to clear most of the graphs contained in my local Virtuoso triple store, using Apache Jena, as part of my clean up process before and after my unit tests. I think that something like this should be done. First, I retrieve the graph URIs to be deleted; then I execute a SPARUL Drop operation.
String sparqlEndpointUsername = ...;
String sparqlEndpointPassword = ...;
String sparqlQueryString = ...; // Returns the URIs of the graphs to be deleted
HttpAuthenticator authenticator = new SimpleAuthenticator(sparqlEndpointUsername,
sparqlEndpointPassword.toCharArray());
ResultSet resultSetToReturn = null;
try (QueryEngineHTTP queryEngine = new QueryEngineHTTP(sparqlEndpoint, sparqlQueryString, authenticator)) {
resultSetToReturn = queryEngine.execSelect();
resultSetToReturn = ResultSetFactory.copyResults(resultSetToReturn);
while(resultSetToReturn.hasNext()){
String graphURI = resultSetToReturn.next().getResource("?g").getURI();
UpdateRequest request = UpdateFactory.create() ;
request.add("DROP GRAPH <"+graphURI+">");
Dataset dataset = ...; // how can I create a default dataset pointing to my local virtuoso installation?
// And perform the operations.
UpdateAction.execute(request, dataset) ;
}
}
;
Questions:
As shown in this example, ARQ needs a dataset to operate on. How would I create this dataset pointing to my local Virtuoso installation for an update operation?
Is there perhaps an alternative to my approach? Would using another approach (apart from jena) be a better idea?
Please note that I am not trying to delete all graphs. I am deleting only the graphs whose names are returned through the SPARQL query defined in the beginning (3rd line).
Your question appears to be specific to Virtuoso, and meant to remove all RDF data, so you could use Virtuoso's built-in RDF_GLOBAL_RESET() function.
This is not a SPARQL/SPARUL query; it is usually issued through an SQL connection -- which could be JDBC, ODBC, ADO.NET, OLE DB, iSQL, etc.
That said, as you are connecting through a SPARUL-privileged connection, you should be able to use Virtuoso's (limited) SQL-in-SPARQL support, a la --
SELECT
( bif:RDF_GLOBAL_RESET() AS reset )
WHERE
{ ?s ?p ?o }
LIMIT 1
(Executing this through an unprivileged connection like the default SPARQL endpoint will result in an error like Virtuoso 37000 Error SP031: SPARQL compiler: Function bif:RDF_GLOBAL_RESET() can not be used in text of SPARQL query due to security restrictions.)
(ObDisclaimer: OpenLink Software produces Virtuoso, and employs me.)
You can build a single SPARQL Update request:
DROP GRAPH <g1> ;
DROP GRAPH <g2> ;
DROP GRAPH <g3> ;
... ;
because in SPARQL Update one HTTP requests can be several update operations, separated by ;.

Use same URL for both query and update

I know that by default fuseki provides different urls for both query and update, allowing some elegant management.
Now, i want to get a single URL for both update and query. The rationale behind this need is to avoid the propagation of two urls in the codebase.
I know that update and query codes should be separated, but my requests are not mixed. It's just to avoid the propagation of two objects instead of one.
My current config looks like:
<#service1> rdf:type fuseki:Service ;
fuseki:name "dataset" ; # http://host:port/dataset
fuseki:serviceQuery "endpoint" ; # SPARQL query service
fuseki:serviceUpdate "endpoint" ; # SPARQL update service
fuseki:dataset <#dataset> ;
.
In theory, an interface exists at /endpoint, but only accept update. When query with:
prefix sfm: <sfm/>
SELECT DISTINCT ?value
WHERE {
sfm:config sfm:component ?value.
}
the server reports many lines like the following:
INFO [4] POST http://localhost:9876/sfm/endpoint
INFO [4] POST /sfm :: 'endpoint' :: [application/x-www-form-urlencoded] ?
INFO [4] 400 SPARQL Update: No 'update=' parameter (0 ms)
I can't find anything in the doc that specify that query and update service can't be at same place, so i'm assume it's possible and i've just missed something.
However the last line of log is explicit: fuseki waits for an update.
One other solution could be to define the url as localhost/dataset/, and depending if i query or update, add the relevant part at the end, giving respectively localhost/dataset/query and localhost/dataset/update.
But (1) this lead the database to need to have a particular url naming, and (2) it looks like a strong requirement about the triplestore: when i will use another one, it will have to provide the same interface, which could be not possible. (don't know if this feature is implemented in other triplestores)
EDIT: fix the POST/GET error
405 HTTP method not allowed: SPARQL Update : use POST
It looks like you are using GET for an SPARQL Update.
It has correctly routed the operation to the update processor (you can use the same endpoint - including dropping the service part and just using the dataset URL).
However, in HTTP, GET are cacheable operations and should not be used when they can cause changes. a GET may not actually reach the end server but some intermediate respond to it from a web cache.
Use POST.
The same is true if you separate services for query and update.
Original Context
The original question has been edited. The original report was asking about this:
INFO [1] 405 HTTP method not allowed: SPARQL Update : use POST (2 ms)
Answer to the revised and different question:
The endpoint for shared services is the dataset URL:
http://localhost:9876/sfm
Whether update, query or services are available is controlled by the configuration file.
Setting fuseki:serviceQuery and fuseki:serviceUpdate the same is not necessary and is discouraged.

SPARQL Update not working

I am trying to perform a simple update of the value of a property that that has a given resource as its subject.
Here is my query:
WITH <http://127.0.0.1:3000/dendro_graph>
DELETE { <http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> ?o0 .
}
INSERT
{
<http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> "creator1" .
}
WHERE { <http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> ?o0 .
}
The result of this is that the delete is executed, but the insert is not; I end up destroying all instances of the property, but no new value is added.
If I remove the WHERE clause, I end up with duplicate triples, because it seems the DELETE is not executed.
What am I doing wrong?
EDIT:
This code produces the duplicates:
WITH <http://127.0.0.1:3000/dendro_graph>
DELETE
{
<http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> ?o0 .
}
INSERT
{
<http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> "creator1" .
}
The query without the WHERE clause is not a legal SPARQL expression, and should have resulted in a syntax error. If the engine you're using accepts this, then that is a bug in that engine.
At first glance, ditto for the earlier operation, which you say deletes but does not insert: as far as I can see the SPARQL expression is correct, and if as you say the insert part does not get executed, that means you've discovered a bug in the engine that executes it. I recommend you get in touch with the developers directly.
Here is a workaround I used to get this working (finally thank God). It seems you can specify several operations to be executed over the graph in a single operation using the semicolon ;.
I ended up specifying the DELETE statement and then the UPDATE one
Check this out for code sample : SPARQL Update example for updating more than one triple in a single query