I would like to know if there is a possibility to retrieve UUID() urn: when using INSERT Statement in SPARQL query ?
My problem is simple but I don't know how to solve it using SPARQL :
I would like to store a lot of timestamp values. Same timestamp can appear multiple times, so I guess I can use UUID() to generate random URI.
I need urn: from UUID() function to relate my new triples.
I'm right ?
Or UUID() is not the solution ?
Thanks for your help.
EDIT :
Ok, so I have to say I would like to retrieve data in my python code.
I am using SPARQLWrapper to run my requests.
If I create one INSERT request like that :
INSERT {
?uuid1 rdf:type capt:ECHANTILLON .
?uuid1 capt:Nom ?uuid1 .
?uuid1 capt:Description '2019-08-07 16:07:34.027636' .
?uuid1 capt:Valeur '1565182189' .
} WHERE {
FILTER NOT EXISTS { ?uuid1 rdf:type capt:ECHANTILLON} .
BIND (UUID() AS ?uuid1) .
};
Then an other INSERT request using ?uuid1 from the first :
INSERT {
?uuid2 rdf:type capt:VALEUR .
?uuid2 capt:Nom ?uuid2 .
?uuid2 capt:Description '2019-08-07 16:07:34.027659' .
?uuid2 capt:Valeur '27.0' .
**?uuid1 capt:A_Pour_Valeur ?uuid2 .** <===
} WHERE {
FILTER NOT EXISTS { ?uuid2 rdf:type capt:VALEUR} .
BIND (UUID() AS ?uuid2) .
};
What I want is :
uuid1 = endpoint.setQuery(request_1)
request_2.addSubject(uuid1)
uuid2 = endpoint.setQuery(request_2)
Something like that.
How can I retrieve ?uuid1 from the first request if INSERT does not return this value ? I would like to make two requests if possible.
Have I to regroup two requests in one request, or have I to run a SELECT ?uuid1 request before running second ?
You can't get the value of the UUID directly from the SPARQL update - if you want to retrieve it via SPARQL somehow, you'll have to do a query after you've inserted it - or, of course, you could adapt your second SPARQL update to do the selection for you by querying for the 'correct' UUID in its WHERE clause.
However, in this case, that looks difficult to do, and I think the easiest solution for you is that you don't create the UUID in the SPARQL operation itself, but instead create it in code and then use that in your query string, e.g. by adding a VALUES clause, something like this:
import uuid
uuid1 = uuid.uuid1()
update = """INSERT { .... }
WHERE { VALUES ?uuid1 { <urn:uuid:""" + uuid1 + """> }
FILTER NOT EXISTS .... (etc) }"""
Related
For a course I follow I have to write several SPARQL queries about Lego sets. I am interested in finding out if there is a Lego theme which has a single package type.
I have the following SPARQL query:
select distinct ?theme ?package_type (count(?theme) as ?amount_of_lego_sets)
where{
?Lego_set rdf:type wd:Q58780257 .
?Lego_set sch:audienceType ?audience .
?Lego_set ex:has_package_information ?package_info .
?audience ex:belongs_to_theme ?theme .
?package_info ex:has_packaging_type ?package_type .
} group by ?theme ?package_type
order by ?theme
Which produces the following output:
As you can see there is one set that has the theme “4 Juniors” and the package type “Polybag”. Now, I am interested in themes like Advanced models or Action Wheelers which only have a single package type. However, I found it challenging to filter for these themes.
What modification to my query could I implement to remove themes which have sets that have more than one package type?
This is an interesting question. I would use FILTER NOT EXISTS to add an atom to the query body, where we make sure that the theme doesn't have two types of packages, like this:
FILTER NOT EXISTS {
?Lego_set2 sch:audienceType ?audience2 .
?Lego_set2 ex:has_package_information ?package_info2 .
#Notice that the 'theme' variable must be the same as the outer query
?audience2 ex:belongs_to_theme ?theme .
?package_info2 ex:has_packaging_type ?package_type1, ?package_type2
FILTER(?pakage_type1 != ?package_type2)}
Thus your full query should be something like:
select distinct ?theme ?package_type (count(?theme) as ?amount_of_lego_sets)
where{
?Lego_set rdf:type wd:Q58780257 .
?Lego_set sch:audienceType ?audience .
?Lego_set ex:has_package_information ?package_info .
?audience ex:belongs_to_theme ?theme .
?package_info ex:has_packaging_type ?package_type .
FILTER NOT EXISTS {
?Lego_set2 sch:audienceType ?audience2 .
?Lego_set2 ex:has_package_information ?package_info2 .
#Notice that the 'theme' variable must be the same as the outer query
?audience2 ex:belongs_to_theme ?theme .
?package_info2 ex:has_packaging_type ?package_type1, ?package_type2
FILTER(?pakage_type1 != ?package_type2)}
} group by ?theme ?package_type
order by ?theme
You could also use the aggregation approach mentioned in the comments, but hopefully this one solves your problem.
SELECT ?Name FROM <http://.../biblio.rdf>
WHERE { ?Aut name ?Name . ?Pub author ?Aut . ?Pub conf ?Conf
FILTER (?Conf IN ( SELECT ?ConfX FROM <http://.../biblio.rdf>
WHERE { ?ConfX series "ISWC" }))}
I have taken the query from http://www.renzoangles.net/files/amw2011.pdf.
Getting the malformed query syntax error when I tried the above format in AWS Neptune.
Please help me fix the above query.
If you want to test that a triple is in the data, which seems to be the intention of the exampel of "FILTER IN SELECT " here, yuo can use FILTER EXISTS
FILTER EXISTS { ?Conf series "ISWC" }
I would like to store a large number of integers in an rdf database (Blazegraph). Those values need to be updated (incremented) with new data, or if missing, created. What's the best way to do that in sparql 1.1? If I was wrtiting it in SQL (MySQL/MariaDB), it would be this, assuming the database is empty at first, and the table's unique key is set to "s,p" (subject and predicate):
-- Inserting or adding A=10, B=1
INSERT INTO tbl (s,p,o) VALUES ('A','cnt',10), ('B','cnt',1)
ON DUPLICATE KEY UPDATE o=o+VALUES(o);
Resulting RDF data:
:A :cnt 10 .
:B :cnt 1 .
Next run:
-- Inserting or adding A=3, C=5
INSERT INTO tbl (s,p,o) VALUES ('A','cnt',3), ('C','cnt',5)
ON DUPLICATE KEY UPDATE o=o+VALUES(o);
Resulting RDF data:
:A :cnt 13 .
:B :cnt 1 .
:C :cnt 5 .
So the question is - how would one construct a SPARQL query to do bulk UPSERT based on existing data and increments, and make it efficient.
PREFIX : <http://example.org/>
DELETE { ?letter :cnt ?outdated }
INSERT { ?letter :cnt ?updated }
WHERE {
VALUES (?letter ?increment) { (:A 10) (:B 1) }
OPTIONAL { ?letter :cnt ?outdated }
BIND ((IF(BOUND(?outdated), ?outdated + ?increment, ?increment)) AS ?updated)
}
I am working in DBPedia. I am having a problem when using group by in Sparql.
I have this code:
SELECT ?res ?titulo
WHERE {
?res rdf:type <http://dbpedia.org/class/yago/JaguaresDeChiapasFootballers> .
?res rdfs:label ?titulo .
}
GROUP BY (?res)
LIMIT 15
I want to return a list of all in this type. But I only want to return one for each URI, I put the group by and it doesn’t work and I really don’t know why?
Can someone help me?
Your original query isn't legal SPARQL. If you paste it into the SPARQL query validator at sparql.org, you'll get the following message:
Non-group key variable in SELECT: ?titulo
If you group by ?res, then you can't select the non-group variable ?titulo. If you just want one ?titulo value per ?res, then you can use …
select ?res (sample(?titulo) as ?title)
…
SPARQL results
If you want a list of the titles, then you can use group_concat to concatenate the titles:
select ?res (group_concat(?titulo;separator=', ') as ?title)
…
SPARQL results
I have my model stored in a triple store(persistence).
I want to select all individuals related by some document name.
I can do it in 2 ways
1) SPARQL request:
PREFIX base:<http://example#>
select ?s2 ?p2 ?o2
where {
{?doc base:fullName <file:/c:/1.txt>; ?p1 ?o1
} UNION {
?s2 ?p2 ?o2 ;
base:documentID ?doc }
}
Question: How to create Jena's Model from the ResultSet?
2) StmtIterator stmtIterator = model.listStatements(...)
The problem with this approach that I need to use model.listStatements(...) operation for the several times :
a) get document URI by document name
b) get a list of individuals ID related to this document URI
c) finally - get a collection of individuals
I concern about performance - 3 times run model.listStatements(...) - many database requests.
Or all data are read into memory(I doubt about it) from the database during model creation:
Dataset ds = RdfStoreFactory.connectDataset(store, conn);
GraphStore graphStore = GraphStoreFactory.create(ds) ;
?
You need to back up a little bit and think more clearly about what you are trying to do. Your sparql query, once it's corrected (see below), will do a perfectly good job of producing an iterator over the resultset, which will provide you with the properties of each of the documents you're looking for. Specifically, you get one set of bindings for each of s2, p2 and o2 for each value in the resultset. That's what you ask for when you specify select ?s2 ?p2 ?o2. And it's normally what you want: usually, we select some values out of the triple store in order to process them in some way (e.g. rendering them into a list on the UI) and for that we exactly want an iterator over the results. You can have the query return you a model not a resultset, by virtue of a SPARQL construct query or SPARQL describe. However, you then have a need to iterate over the resources in the model, so you aren't much further forward (except that your model is smaller and in-memory).
Your query, incidentally, can be improved. The variables p1 and o1 make the query engine do useless work since you never use them, and there's no need for a union. Corrected, your query should be:
PREFIX base:<http://example#>
select ?s2 ?p2 ?o2
where {
?doc base:fullName <file:/c:/1.txt> .
?s2 base:documentID ?doc ;
?p2 ?o2 .
}
To execute any query, select, describe or construct, from Java see the Jena documentation.
You can efficiently achieve the same results as your query using the model API. For example, (untested):
Model m = ..... ; // your model here
String baseNS = "http://example#";
Resource fileName = m.createResource( "file:/c:/1.txt" );
// create RDF property objects for the properties we need. This can be done in
// a vocab class, or automated with schemagen
Property fullName = m.createProperty( baseNS + "fullName" );
Property documentID = m.createProperty( baseNS + "documentID" );
// find the ?doc with the given fullName
for (ResIterator i = m.listSubjectsWithProperty( fullName, fileName ); i.hasNext(); ) {
Resource doc = i.next();
// find all of the ?s2 whose documentID is ?doc
for (StmtIterator j = m.listStatements( null, documentID, doc ); j.hasNext(); ) {
Resource s2 = j.next().getSubject();
// list the properties of ?s2
for (StmtIterator k = s2.listProperties(); k.hasNext(); ) {
Statement stmt = k.next();
Property p2 = stmt.getPredicate();
RDFNode o2 = stmt.getObject();
// do something with s2 p2 o2 ...
}
}
}
Note that your schema design makes this more complex that it needs to be. If, for example, the document full name resource had a base:isFullNameOf property, then you could simply do a lookup to get the doc. Similarly, it's not clear why you need to distinguish between doc and s2: why not simply have the document properties attached to the doc resource?
Finally: no, opening a database connection does not load the entire DB into memory. However, TDB in particular does make extensive use of caching of regions of the graph in order to make queries more efficient.