Replace null values with '' 'sem:sparql' output json in MarkLogic - sparql

I using ML 8.0-6.3
I am using sem:sparql() function to run the SPARQL queries.
If there is no triple for a particular variable(variables are in OPTIONAL block) I am getting null value in the JSON output.
Is there any work around in MarkLogic to replace the null values with "".
Like:
coming output:
{
"ncFacetIri": "http://www.test.com/facet/UL",
"acronym": "UL",
"acronym1": null
}
expected json output:
{
"ncFacetIri": "http://www.test.com/facet/UL",
"acronym": "UL",
"acronym1": ""
}
This way I am converting the sem:sparql output to JSON objects:
<a>{sem:sparql($query)}</a>/json:object ! json:object(.)
Please help.

You can use COALESCE for that:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT ?subject ?type (COALESCE(?l, "") as ?label)
WHERE {
?subject rdf:type ?type.
OPTIONAL {
?subject rdfs:label ?l.
}
}
HTH!

Related

field type mapping error in CONSTRUCT SPARQL query

I am trying to check whether the literal value of this triple: <resource1> skos:altSymbol "literal values of resource2" exists as resource <resource2> in my endpoint.
If yes I would like to construct a new triple <resource1> predicate <resource2>.
I run the following query but got an error.
I don't know what is wrong with the query. If someone can help me or suggest me a different way to proceed. It could be great!
Thanks
Pierre
Sparql Endpoint: http://agrold.southgreen.fr/sparql
System is OpenLink Virtuoso 7.2.5 opensource (linux)
BASE <http://www.southgreen.fr/agrold/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX vocab: <vocabulary/>
PREFIX resource: <resource/>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX sio: <http://semanticscience.org/resource/>
CONSTRUCT { ?protein_id sio:SIO_000339 ?existURI . }
WHERE
{
?protein_id ?p ?o ;
rdfs:label ?label ;
skos:altSymbol ?symbol ;
obo:RO_0002162 <http://identifiers.org/taxonomy/39947> .
BIND ( CONCAT ( str ( resource: ) , str ( ?symbol ) ) AS ?uri)
FILTER IF ( EXISTS { ?uri rdf:type vocab:Gene } , ?uri , "None" )
BIND ( URI ( ?uri ) as ?existURI )
}
LIMIT 100
returning error = Virtuoso 37000 Error SP031: SPARQL compiler: Internal error: sparp_check_field_mapping_spo(): field is neither variable nor literal?
As seen in comments, this query revision resolves the issue --
CONSTRUCT
{ ?protein_id sio:SIO_000339 ?existURI . }
WHERE
{
{ ?protein_id ?p ?o ;
rdfs:label ?label ;
skos:altSymbol ?symbol ;
obo:RO_0002162 <http://identifiers.org/taxonomy/39947> .
BIND ( URI ( CONCAT ( str ( resource: ) , str ( ?symbol ) ) ) AS ?uri)
}
BIND ( If ( EXISTS { ?uri rdf:type vocab:Gene } , ?uri , "None" ) AS ?existURI )
}
LIMIT 100

How to get `filter not exists` query working with ARC2?

I have an ARC2 based RDF store setup and filled with some data. The following query returns the expected results (all URIs of things of type vcard:Individual or foaf:Person) when I run it without the FILTER NOT EXISTS part:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX app: <http://example.com#>
SELECT ?person
WHERE {
?person rdf:type ?type .
FILTER (?type = vcard:Individual || ?type = foaf:Person)
FILTER NOT EXISTS {
?person app:id ?id
}
}
When I try to exclude those things having the app:id property by running the full query, it fails with the following message:
Incomplete FILTER in ARC2_SPARQLPlusParser
Incomplete or invalid Group Graph pattern. Could not handle " FILTER NOT EXISTS { " in ARC2_SPARQLPlusParser
When testing the query in the query validator on sparql.org, there are no issues. Is there something wrong with my query that I am missing or is this a shortcoming of ARC2?
Can you think of an alternative query that I can try with ARC2 to get the desired result?
ARC2 does not support SPARQL 1.1, thus, you have to use the common OPTIONAL-FILTER(!BOUND()) pattern:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX app: <http://example.com#>
SELECT ?person
WHERE {
?person rdf:type ?type .
FILTER (?type = vcard:Individual || ?type = foaf:Person)
OPTIONAL {
?person app:id ?id
}
FILTER ( !BOUND(?id) )
}

SPARQL Matching Literals with **ANY** Language Tags without run into timeout

I need to select the entity that have a "taxon rank (P105)" of "species (Q7432)" which have a label that match a literal string such as "Topinambur".
I'm testing the queries on https://query.wikidata.org;
this query goes fine and return the entity to me with satisfying response time:
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT * WHERE {
?entity rdfs:label "Topinambur"#de .
?entity wdt:P105 wd:Q7432.
}
LIMIT 100
The problem here is that my requisite is not to specify the language but the lexical forms of the labels in the underlying dataset ( wikidata) has language tags so i need a way to get Literal Equality for any language.
I tried some possible solution but I didn't find any query that didn't result in the following:
TIMEOUT message com.bigdata.bop.engine.QueryTimeoutException: Query deadline is expired
Here the list of what I tried (..and I always get TIMEOUT) :
1) based on this answer I tried:
SELECT * WHERE {
?entity rdfs:label ?label FILTER ( str( ?label ) = "Topinambur") .
?entity wdt:P105 wd:Q7432.
}
LIMIT 100
2) based on some other documentation I tried:
SELECT * WHERE {
?entity wdt:P105 wd:Q7432.
?entity rdfs:label ?label FILTER regex(?label, "^Topinambur") .
}
LIMIT 100
3) and
SELECT * WHERE {
?entity wdt:P105 wd:Q7432.
?entity rdfs:label ?label .
FILTER langMatches( lang(?label), "*" )
FILTER (?label = "Topinambur")
}
LIMIT 100
What I'm looking for is a performant solution or some SPARQL syntax the doesn't end up to a TIMEOUT message.
PS: with reference to http://www.rfc-editor.org/rfc/bcp/bcp47.txt I don't understand if language ranges or ```wildcards`` could help in some way.
EDIT
I successfully tested (without falling timeout) a similar query in DbPedia by using virtuoso query editor at:
https://dbpedia.org/sparql
Default Data Set Name (Graph IRI):http://dbpedia.org
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?resource
WHERE {
?resource rdfs:label ?label . FILTER ( str( ?label ) = "Topinambur").
?resource rdf:type dbo:Species
}
LIMIT 100
I am still very interested in understanding the performance problem that I experience on Wikidata and what is the best syntax to use.
I solved similar problem - want to find entity with label string in any language. I recommend do not use FILTER, because it is too slow. Rather use UNION like this:
SELECT ?entity WHERE {
?entity wdt:P105 wd:Q7432.
{ ?entity rdfs:label "Topinambur"#de . }
UNION { ?entity rdfs:label "Topinambur"#en . }
UNION { ?entity rdfs:label "Topinambur"#fr . }
}
GROUP BY ?entity
LIMIT 100
Try it!
This solution is not perfect, because you have to enumater all languages, but is fast and reliable. List of all available wikidata language are here.
This answer proposes three options:
Be more specific.
The ?entity wdt:P171+ wd:Q25314 pattern seems to be sufficiently selective in your case.
Wait until they implement full-text search.
Use Quarry (example query).
Another option is to use Virtuoso full-text search capabilities on wikidata.dbpedia.org:
SELECT ?s WHERE {
?resource rdfs:label ?label .
?label bif:contains "'topinambur'" .
BIND ( IRI ( REPLACE ( STR(?resource),
"http://wikidata.dbpedia.org/resource",
"http://www.wikidata.org/entity"
)
) AS ?s
)
}
Try it!
It seems that even the query below sometime works on wikidata.dbpedia.org without falling into timeout:
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?resource WHERE {
?resource rdfs:label ?label .
FILTER ( STR(?label) = "Topinambur" ) .
}
Try it!
Two hours ago I've removed this statement on Wikidata:
wd:Q161378 rdfs:label "topinambur"#ru .
I'm not a botanist, but 'topinambur' is definitely not a word in Russian.
Working further on from #quick's answer, and showing it for lexemes rather than labels. First identifying relevant language codes:
SELECT (GROUP_CONCAT(?mword; separator=" ") AS ?mwords) {
BIND(1 AS ?dummy)
VALUES ?word { "topinambur" }
{
SELECT (COUNT(?lexeme) AS ?count) ?language_code {
?lexeme dct:language / wdt:P424 ?language_code .
}
GROUP BY ?language_code
HAVING (?count > 100)
ORDER BY DESC(?count)
}
BIND(CONCAT('"', ?word, '"#', ?language_code) AS ?mword)
}
GROUP BY ?dummy
Try it!
Followed by the verbose query
SELECT (COUNT(?lexeme) AS ?count) ?language (GROUP_CONCAT(?word; separator=" ") AS ?words) {
VALUES ?word { "topinambur"#eo "topinambur"#ko "topinambur"#bfi "topinambur"#nl "topinambur"#uk "topinambur"#cy "topinambur"#pt "topinambur"#zh "topinambur"#br "topinambur"#bg "topinambur"#ms "topinambur"#tg "topinambur"#se "topinambur"#ta "topinambur"#non "topinambur"#it "topinambur"#zh-min-nan "topinambur"#nan "topinambur"#fi "topinambur"#jbo "topinambur"#ml "topinambur"#ja "topinambur"#ku "topinambur"#bn "topinambur"#ar "topinambur"#nb "topinambur"#es "topinambur"#pl "topinambur"#nn "topinambur"#sk "topinambur"#da "topinambur"#de "topinambur"#cs "topinambur"#fr "topinambur"#sv "topinambur"#eu "topinambur"#he "topinambur"#la "topinambur"#en "topinambur"#ru }
?lexeme dct:language ?language ;
ontolex:lexicalForm / ontolex:representation ?word .
}
GROUP BY ?language
Try it!
For querying on labels, do something similar to:
SELECT (COUNT(?item) AS ?count) ?language (GROUP_CONCAT(?word; separator=" ") AS ?words) {
VALUES ?word { "topinambur"#eo "topinambur"#ko "topinambur"#bfi "topinambur"#nl "topinambur"#uk "topinambur"#cy "topinambur"#pt "topinambur"#zh "topinambur"#br "topinambur"#bg "topinambur"#ms "topinambur"#tg "topinambur"#se "topinambur"#ta "topinambur"#non "topinambur"#it "topinambur"#zh-min-nan "topinambur"#nan "topinambur"#fi "topinambur"#jbo "topinambur"#ml "topinambur"#ja "topinambur"#ku "topinambur"#bn "topinambur"#ar "topinambur"#nb "topinambur"#es "topinambur"#pl "topinambur"#nn "topinambur"#sk "topinambur"#da "topinambur"#de "topinambur"#cs "topinambur"#fr "topinambur"#sv "topinambur"#eu "topinambur"#he "topinambur"#la "topinambur"#en "topinambur"#ru }
?item rdfs:label ?word ;
}
GROUP BY ?language

apparently unnecessary SPARQL filter

Given the graph http://example.org/ as:
#prefix foaf:<http://xmlns.com/foaf/0.1/purl>.
<uri:alice> foaf:name "Alice".
<uri:bob> foaf:name "Bob".
<uri:carl> foaf:name "Carl".
Why this SPARQL query works:
PREFIX foaf:<http://xmlns.com/foaf/0.1/purl>
SELECT *
WHERE {
GRAPH <http://example.org/> {
?model_ic foaf:name ?name.
FILTER (?name = "Bob")
}
}
Whereas this one don't (well, technically it works but returns 0 matches)
PREFIX foaf:<http://xmlns.com/foaf/0.1/purl>
SELECT *
WHERE {
GRAPH <http://example.org/> {
?model_ic foaf:name "Bob".
}
}
If there is any other attachment to the name rather only the string you might have issues. For example, foaf:name normally has a language attached. Try:
PREFIX foaf:<http://xmlns.com/foaf/0.1/purl>
SELECT *
WHERE {
GRAPH <http://example.org/> {
?model_ic foaf:name "Bob"#en.
}
}

SPARQL Query Error with OPTION(TRANSITIVE) on Jena

I have the following Query
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?type
WHERE
{
{
SELECT *
WHERE
{
?x rdfs:subClassOf ?type .
}
}
OPTION (TRANSITIVE, t_distinct, t_in (?x), t_out (?type) ) .
FILTER (?x = <http://dbpedia.org/ontology/Hospital>)
}
It works fine when i send it to Virtuoso endpoint but does not work on my Jena instance. In specific i get the following error:
INFO [1] 400 Parse error:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?type
WHERE
{
{
SELECT *
WHERE
{
?x rdfs:subClassOf ?type .
}
}
OPTION (TRANSITIVE, t_distinct, t_in (?x), t_out (?type) ) .
FILTER (?x = <http://dbpedia.org/ontology/Hospital>)
}
Lexical error at line 12, column 39. Encountered: " " (32), after : "OPTION" (17 ms)
In case this a Virtuoso specific function, I would appreciate to know an equivalent for this query that would work with *Jena/Standard SPARQL). The expected output should be:
http://dbpedia.org/ontology/Building
http://dbpedia.org/ontology/ArchitecturalStructure
http://dbpedia.org/ontology/Place
http://dbpedia.org/ontology/d0:Location
which represents all superclasses for "Hospital"
This is the expected behavior. This part of the query:
OPTION (TRANSITIVE, t_distinct, t_in (?x), t_out (?type) )
is not standard SPARQL 1.1 but it is a Virtuoso specific extension.
Jena is a SPARQL 1.1 compliant implementation.
The following query does the same thing using standard SPARQL 1.1 syntax, and should work with both Fuseki and Virtuoso (just tested on the dbpedia endpoint and got the same result):
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?type
WHERE
{
{
SELECT *
WHERE
{
?x rdfs:subClassOf+ ?type .
}
}
FILTER (?x = <http://dbpedia.org/ontology/Hospital>)
}
The feature used is the "property path".
See http://www.w3.org/TR/sparql11-query/