How do i make sparql query only about data type name? - sparql

How to display data's property label?
I working for dbpedia ontology,
I want to make a sparql query, below is my sample query. This result is mix up either datatype or object type, I want to datatype property name.
SELECT ?p ?pLabel ?domain ?range
{
?p rdfs:domain http://dbpedia.org/ontology/Person> .
}
ex: Following is data type example, but I cannot select only datatype, I want to display
type name.
"chat"
'chat'#fr with language tag "fr"
"xyz"^^<http://example.org/ns/userDatatype>
"abc"^^appNS:appDataType
'''The librarian said, "Perhaps you would enjoy 'War and Peace'."'''
1, which is the same as "1"^^xsd:integer
1.3, which is the same as "1.3"^^xsd:decimal
1.300, which is the same as "1.300"^^xsd:decimal
1.0e6, which is the same as "1.0e6"^^xsd:double
true, which is the same as "true"^^xsd:boolean
false, which is the same as "false"^^xsd:boolean
expect to result
Expect to result (only data type)
typename <- field name
string <- type name
int
boolean
int
double
boolean
How to make a sparql query?

Use function datatype() for that purpose. For example:
select distinct ?y datatype(?z)
{
?x a <http://dbpedia.org/class/yago/JeskolaBuzzUsers>.
?x ?y ?z.
filter (datatype(?z) != '')
}

PREFIX xsd: http://www.w3.org/2001/XMLSchema#
ASK WHERE
{
?item dm:amount ?amount .
FILTER ((datatype(?amount)) != xsd:integer)
}
The query engine still knew which ?amount values were integers and which were not,
because any unquoted series of digits with no period is treated as an integer.
Most of your work with datatypes in SPARQL will involve the use of functions that are
covered in more detail in the next section. Before we look at any of those, it’s a good
idea to know how representations of typed literals in your queries interact with different
kinds of literals in your dataset.

Related

How can I use SPARQL to find instances where two properties do not share any of the same objects?

In my company's taxonomy, all concepts have a value for skos:prefLabel, and most have a bunch of values for a custom property -- let's call it ex:keyword -- whose values have the datatype rdf:langString. I want to find concepts where the value of skos:prefLabel does NOT exactly match ANY value of ex:keyword, when case and language are ignored.
It is fairly straightforward to write a query for concepts where the values DO match, like this:
SELECT *
WHERE {
?concept skos:prefLabel ?label ;
ex:keyword ?kw
FILTER (lcase(str(?label)) = lcase(str(?kw)))
}
Where I'm getting tripped up is in trying to negate this.
Using != in the FILTER would just return a bunch of cases where ?label and ?kw don't match, which is not what I'm after.
What I would like is to be able to use a FILTER NOT EXISTS, but that's invalid with an expression like (?a = ?b); it only works with something like {?a ?b ?c}.
I suspect that there is a proper way to express FILTER NOT EXISTS (?a = ?b) in SPARQL, but I don't know what it is. Can someone help?
The trick is to put the triple pattern for matching the keyword in the FILTER NOT EXISTS, like so:
SELECT *
WHERE {
?concept skos:prefLabel ?label .
FILTER NOT EXISTS { ?concept ex:keyword ?kw .
FILTER(lcase(str(?label)) = lcase(str(?kw)))
}
}
This query says "I want all concepts with a preflabel such that the concept has no keyword value that matches that prefLabel".

DBPedia: all population fields?

I am trying to extract all entities in DBPedia that have a population. However, I have found that there are different field names for population depending on the entity. For instance, http://dbpedia.org/page/Boston has the field populationTotal while http://dbpedia.org/page/Alaska has the field 2010pop. Is there a complete list of the population fields that I can query for?
Solution via #AKSW above: query for all properties that start with "pop" and have a specified range.
SELECT ?p ?range {
?p a rdf:Property
FILTER(regex(str(?p), "pop"))
OPTIONAL {?p rdfs:range ?range}
}

SPARQL search query

I have some RDF data structured like this:
[ pref:ip_address "127.0.0.1" ;
pref:time "1459630844.482" ;
pref:url "https://google.com" ;
pref:user "johndoe"
] .
I need query that will return all results matching given IP, time frame (between from time and end time), url (even partial match) and user (also even partial match).
What I have now is simple query to get results based on single value, like this:
PREFIX pref: <http://something> SELECT DISTINCT * WHERE { ?u pref:user USER_VALUE . ?u ?p ?o . }
This returns all results with given user but only if given username is full match. Meaning it will return all results for johndoe if USER_VALUE is johndoe but not if it is john.
My knowledge of SPARQL is extremely limited and I appreciate any help. Thank you.
To do anything more than exact match, you need to use a FILTER and use operations like CONTAINS or REGEX.
Example:
{ ?u pref:user ?user .
?u ?p ?o .
FILTER( CONTAINS(?user, "john") )
}
There are a number of FILTER functions that may be useful including REGEX. See the spec for details.

How to check prefix of variables in SPARQL?

I want to find how many resource is there in an RDF but I can't find any tutorial to explain how can I check the prefix of variables in my SPARQL.
I have tried this:
select count(?x) where {
res:?x ?p ?v
}
but it has syntax error. I am using virtuoso for DBPedia
You can use strstarts(string,prefix) to check whether string begins with prefix. You can use the str function to get the string representation of a IRI, including IRIs generated from prefixes. E.g., if you have prefix ex: <http://example.org/>, then ex: by itself is a legal IRI, and str(ex:) produces "http://example.org/". That means that you can check whether an IRI that is the value of a variable ?x begins with some particular prefix p: by doing strstarts(str(?x),str(p:)). Then you can filter on that, or count it, etc.
Here's an example that binds ?thing to a few different values, some of which begin with the dbpedia-owl: prefix:
select * where {
values ?thing { dbpedia-owl:a dbpedia-owl:b dbpprop:c }
bind( strstarts(str(?thing),str(dbpedia-owl:)) as ?startsWithDBpediaOwl )
}
SPARQL results (a and b get true, c gets false)
You can filter on that too, and then count the results:
select (count(*) as ?n) where {
values ?thing { dbpedia-owl:a dbpedia-owl:b dbpprop:c }
filter strstarts(str(?thing),str(dbpedia-owl:))
}
SPARQL results (2)

Filter language only if the type is literal

This is probably almost the same quetion as:
Filter by language only if the object is a literal
Problem is that the answer there doesn't work in my case.
I have this query:
SELECT ?property ?value
WHERE { <http://dbpedia.org/resource/Facebook> ?property ?value
FILTER(STRSTARTS(STR(?property), "http://dbpedia.org/property") || STRSTARTS(STR(?property), "http://dbpedia.org/ontology"))}
Result in Virtuoso
There you would see a list of properties including "alexa rating 2" and "abstract" in many languages.
If I then try the suggested solution in the mentioned question above:
SELECT ?property ?value
WHERE { <http://dbpedia.org/resource/Facebook> ?property ?value
FILTER(STRSTARTS(STR(?property), "http://dbpedia.org/property") || STRSTARTS(STR(?property), "http://dbpedia.org/ontology"))
FILTER(!isLiteral(?value) || langMatches(lang(?value), "EN"))}
Result in Virtuoso
Now you would see that only english version of "abstract" is there but "alexa rating 2" and many other non-string values are gone.
Anyone that knows how to get all properties as in the first query and then for literals only filter out the english language?
Your second query does filter out literals that have a language tag other than English. In RDF 1.0, there are three types of literals:
plain literals (no datatype, and no language tag)
language tagged literals (a string and a language tag)
datatype literals (a lexical form and a datatype)
So the Alexa rating, which has a value of 2, is a literal, and it doesn't have a language tag, so the language tag certainly isn't "EN" (and more importantly, doesn't match "EN"; langMatches does some more complex checks). What you want is to filter out non-English language tagged literals. That's not hard; you just need to add lang(?value) = "" to the filter (since lang returns "" for literals with no language tag):
SELECT ?property ?value
WHERE { <http://dbpedia.org/resource/Facebook> ?property ?value
FILTER(STRSTARTS(STR(?property), "http://dbpedia.org/property") || STRSTARTS(STR(?property), "http://dbpedia.org/ontology"))
FILTER(!isLiteral(?value) || lang(?value) = "" || langMatches(lang(?value), "EN"))}
SPARQL results
The way to read that filter is:
Keep values that
are not literals; or
are literals, but don't have a language tag; or
are literals with a language tag that matches "en".
So it sounds like you simply want to invert the filter condition on the language right?
In which case you simply need to invert the langMatches call by adding a ! before it i.e. adding the not operator to it:
SELECT ?property ?value
WHERE { <http://dbpedia.org/resource/Facebook> ?property ?value
FILTER(STRSTARTS(STR(?property), "http://dbpedia.org/property") || STRSTARTS(STR(?property), "http://dbpedia.org/ontology"))
FILTER(!isLiteral(?value) || !langMatches(lang(?value), "EN"))}
Result in DBPedia
With this simple change the English entries are now eliminated and I see only the non-English entries.