Filter on annotation - SPARQL

2019-08-14 17:52发布

问题:

I want to query my ontology based on annotations with datatype of float and string. For instance I have an individual that has an annotation "EBC_value" of type float and an annotation "Label" of type String.

How do I do this? I have tried with REGEX, like this, but it doesn´t work. I don´t get any errors, just no results.

PREFIX ont: <http://vestbrygg.no/ontologies/beer.owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT  ?title
WHERE   { ?x ont:title ?title
          FILTER regex(?title, "Sack") 
        }

Hope you guys can help. Thanks.And yeah, unless you want to see and test the entire ontology, the code for the annotations are like this:

<NamedIndividual rdf:about="&beer;Base_malt_-_Best_Malz">
    <rdf:type rdf:resource="&beer;Light"/>
    <beer:EBC_value rdf:datatype="&xsd;float"></beer:EBC_value>
    <beer:Label rdf:datatype="&xsd;string">Sack</beer:Label>
</NamedIndividual>

回答1:

Your query bears no relation to your data which is why you get no results.

Firstly the ont:title property that your query references does not appear to exist in your data.

Secondly your namespaces don't appear to align, I assume the ont namespace in your query is supposed to be the same namespace as the beer namespace in your RDF/XML but you haven't shown the namespaces so I can only guess at this. Even though namespaces are mostly a convenience mechanism it's best to be consistent with your use of prefixes because it'll make things a lot less confusing.

Thirdly there should be absolutely no need to use REGEX() you simply need to use an appropriate graph pattern:

PREFIX beer: <http://vestbrygg.no/ontologies/beer.owl#>

SELECT ?x
WHERE
{
  ?x beer:Label "Sack" .
}

Since beer:Label is a property you can access it directly in your query. This will find you all individuals where the beer:Label property has the value Sack, if you want to do a partial match on the search string you can always use the CONTAINS() function which will be faster than REGEX():

PREFIX beer: <http://vestbrygg.no/ontologies/beer.owl#>

SELECT ?x
WHERE
{
  ?x beer:Label ?label .
  FILTER(CONTAINS(?label, "Sack"))
}

This will find all individuals where there is a beer:Label and it contains the value Sack

Edit

To answer your comment, matching typed values requires you to know what the type of the values are, assuming you are using xsd:float then you'd query like the following:

PREFIX beer: <http://vestbrygg.no/ontologies/beer.owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?x
WHERE
{
  ?x beer:EBC_value "4.8"^^xsd:float .
}