Matching optional triples without using OPTIONAL

喜夏-厌秋 提交于 2019-12-11 20:33:52

问题


I want to query records where not all records have all properties. Is it possible to get them with blank values by just using basic graph patterns in the query and without using optional?


回答1:


A variable has to be bound to some value in order for there to be a match. The exception is with optional. There you can get a match where it's optional for a particular pattern to have matched. If you want an optional variable for a match, you'll have to use optional.

Technically, you could avoid using optional by using a union with the different partial matchings that could occur. In that sense, you wouldn't be using optional, but it'd be even more complex:

@prefix : <urn:ex:>.

:a :hasName "Person A".

:b :hasAge 32 .

:c :hasName "Person C" ;
   :hasAge 71 .
prefix : <urn:ex:>

select * where {
  #-- ?age but no name
  { ?person :hasAge ?age
    filter not exists { ?person :hasName ?name }}
  union
  #-- ?name but no age
  { ?person :hasName ?name
    filter not exists { ?person :hasAge ?age }}
  union
  #-- ?name and ?age
  { ?person :hasName ?name ; :hasAge ?age }
}
-----------------------------
| person | age | name       |
=============================
| :a     |     | "Person A" |
| :b     | 32  |            |
| :c     | 71  | "Person C" |
-----------------------------



回答2:


You can achieve this by using a CONSTRUCT query. Use a CONSTRUCT with a simple BGP to retrieve the relevant subset of your complete dataset, and then post-process that result.

For example, imagine you have a set of records about persons, where there are names, e-mail addresses, phone numbers, but not necessarily all of these properties are filled out for every person.

You can then just do a query that retrieves all properties for resources of type Person. Here's an example in Java (using Sesame API):

// query to retrieve all properties of things of type Person
String queryString = "CONSTRUCT WHERE {?s a <urn:Person>; ?p ?o }";
GraphQuery query = conn.prepareGraphQuery(SPARQL, queryString);
Model result = QueryResults.asModel(query.evaluate());

You now have a query result that contains all available person-data. Dealing with potentially missing values is now just a question of processing the result. For example:

for (Resource person: result.subjects()) {
   Literal name = result.filter(person, FOAF.NAME, null).objectLiteral(); 
   if (name == null) {
       System.out.println("name is missing!");
   }
   else {
       ...
   }
}


来源:https://stackoverflow.com/questions/29903480/matching-optional-triples-without-using-optional

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!