我有一个图G
。我想通过从G'
过滤掉属于特定类型的所有项(例如{G
,{{1})中创建G
(:Foo
的子集) }}。
例如,如果它是:Bar
G
:x a :Foo
:y a :Bar
:x :predicate_a :hh
:kk :predicate_b :y
:mm :predicate_b :kk
应该是:
G'
我的 best 当前选项是在:mm :predicate_b :kk
上使用DELETE
。每种类型我需要两个查询:
(i)一个主题
G
(i)另一个对象
delete where
{
?s ?p ?o .
?s a :Foo .
}
那样,我应该得到我所需要的。在我看来,这不是最佳选择。有没有更好的方法(例如,效率更高/更紧凑)?
答案 0 :(得分:2)
可以使用UNION
和VALUES
在单个查询中完成。这应该一次就适用于两个课程:
PREFIX : <http://www.example.com/foo#>
DELETE { ?s ?p ?o }
WHERE
{
VALUES (?toDeleteClass) {
(:Foo)
(:Bar)
}
?toDelete a ?toDeleteClass
# or, if you want transitivity: ?toDelete a/rdfs:subClassOf* ?toDeleteClass
{ BIND( ?toDelete AS ?s ). ?s ?p ?o }
UNION { BIND( ?toDelete AS ?o ). ?s ?p ?o }
}
将此问题与您的问题下的注释相结合,您可以构建一个新的图形G',而不用修改现有图形(使用INSERT
和GRAPH
),或者使用CONSTRUCT
,您可以提取并下载G'(但在这种情况下,您可能需要通过LIMIT
/ OFFSET
来分批处理,因为许多三元存储都限制了查询可以返回的结果大小)
VALUES
可以替代FILTER ( ?toDeleteClass IN ( :Foo, :Bar )
。但是,VALUES
对于您所完成的任务而言看起来更自然,并且可能也会更快。
当心推断:如果默认情况下您的三元存储区启用了某些推断,则模式?toDelete a ?toDeleteClass
也可能会选择Foo / Bar的可传递实例,即那些是Foo / Bar子类的实例,而不仅仅是直接的。如果您不希望这样做,那么最好的方法就是找到如何在三元组存储中禁用推论(您可以通过FILTER
检测到间接实例,但是它更复杂,更慢)。