在不使用 OPTIONAL 的情况下匹配可选的三元组

Matching optional triples without using OPTIONAL

我想查询并非所有记录都具有所有属性的记录。是否可以通过在查询中使用基本图形模式而不使用 optional?

来获取它们的空白值

变量必须绑定到某个值才能匹配。 optional 除外。在那里你可以得到一个匹配,其中 optional 匹配特定模式。如果你想要一个 optional 变量来匹配,你必须使用 optional.

从技术上讲,您可以通过使用具有可能发生的不同部分匹配的 union 来避免使用 optional。从这个意义上说,您不会使用可选的,但它会更加复杂:

@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" |
-----------------------------

您可以使用 CONSTRUCT 查询来实现此目的。使用带有简单 BGP 的 CONSTRUCT 来检索完整数据集的相关子集,然后 post 处理该结果。

例如,假设您有一组关于人员的记录,其中包含姓名、电子邮件地址、phone 号码,但不一定为每个人填写所有这些属性。

然后您可以执行一个查询来检索 Person 类型资源的所有属性。这是 Java 中的示例(使用 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());

您现在有一个包含所有可用人员数据的查询结果。处理潜在的缺失值现在只是处理结果的问题。例如:

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