Search code examples
sparqljenaowl

I want to return a result in SPARQL only if a property exists and has a specified value


I have an owl ontology where I consider that a Zone element is tasked if it has an associated Mission and this Mission is tasked.

The Zoneclass in my ontology: http://myontology/Zone

  • with the following object property: http://myontology/hasMission where the target is http://myontology/Mission
  • and the following string data property: http://myontology/label

The Mission class: http://myontology/Mission

  • with the following boolean data property: http://myontology/tasked

I want to know if a particular Zone is tasked. It means that it has the hasMission object property, and that the target Mission has a tasked data property with the value true.

I tried something like:

SELECT ?label ?tasked
WHERE {
  ?zone rdf:type myontology:Zone .
  ?zone myontology:label "ZoneName" .
  ?zone myontology:label ?label .
  ?mission rdf:type myontology:Mission .
  OPTIONAL { ?mission myontology:tasked ?tasked }
  OPTIONAL { ?zone myontology:hasMission ?mission }
}

Unfortunately if there is one tasked Mission in the ontology, I always get true for the ?tasked variable, even if there is no Mission associated with the Zone, such as:

----------------------
| label | tasked |
======================
| "ZoneName" | "true"  |
----------------------

I would have liked to have this kind of result if the Zone is not associated to a Mission:

----------------------
| label | tasked |
======================
| "ZoneName" |   |
----------------------

What did I do wrong?

Note that I can't do:

SELECT ?label ?tasked
WHERE {
  ?zone rdf:type myontology:Zone .
  ?zone myontology:label "ZoneName" .
  ?zone myontology:label ?label .
  ?mission rdf:type myontology:Mission .
  OPTIONAL { ?mission myontology:tasked ?tasked }
  ?zone myontology:hasMission ?mission
}

Because in this case I the query will not return any result if the Zone is not associated with a Mission.


Solution

  • It seems that this query fix my problem, uninformeduser was right! :

    SELECT ?label ?tasked
    WHERE {
      ?zone rdf:type myontology:Zone .
      ?zone myontology:label "ZoneName" .
      ?zone myontology:label ?label .
      ?mission rdf:type myontology:Mission .
      OPTIONAL { 
       ?mission myontology:tasked ?tasked .
       ?zone myontology:hasMission ?mission 
      }
    }
    

    I think that the reason is because in my original try the two OPTIONAL are separate, so the engine look at them separately.