我想查询并非所有记录都包含所有属性的记录。是否可以通过在查询中使用基本图形模式并且不使用可选来获取空白值?
答案 0 :(得分:4)
变量必须绑定到某个值才能匹配。例外情况是可选。在那里,您可以获得一个匹配,其中可选匹配特定模式。如果您想要匹配的可选变量,则必须使用可选。
从技术上讲,您可以通过使用 union 来避免使用可选项,并使用可能发生的不同部分匹配。从这个意义上说,你不会使用可选项,但它会更复杂:
@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" |
-----------------------------
答案 1 :(得分:2)
您可以使用CONSTRUCT查询来实现此目的。使用带有简单BGP的CONSTRUCT来检索整个数据集的相关子集,然后对该结果进行后处理。
例如,假设您有一组关于人的记录,其中有姓名,电子邮件地址,电话号码,但不一定所有这些属性都填写给每个人。
然后,您可以执行查询,以检索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 {
...
}
}