我有一个数据集,其中我试图将符合某些条件的个人替换为另一个人。在提供的最小示例中,我希望将x-data://old
替换为x-data://new
。
示例输入数据集:
<x-data://new> <x-dom://betterThan> <x-data://old> .
<x-data://o0> <x-data://p> <x-data://old> .
<x-data://old> <x-data://p> <x-data://o1> .
所需输出数据集的示例:
<x-data://new> <x-dom://betterThan> <x-data://new> .
<x-data://o0> <x-data://p> <x-data://new> .
<x-data://new> <x-data://p> <x-data://o1> .
我试图通过以下查询执行此操作:
DELETE {
?s ?p ?o .
}
INSERT {
?ns ?p ?no .
}
WHERE
{ { SELECT ?new ?old
WHERE
{
?new <x-dom://betterThan> ?old .
FILTER( !sameTerm( ?new, ?old ) ) .
}
LIMIT 1
}
{ ?old ?p ?o
BIND(?old AS ?s)
BIND(?new AS ?ns)
BIND(?o AS ?no)
}
UNION
{ ?s ?p ?old
BIND(?old AS ?o)
BIND(?s AS ?ns)
BIND(?new AS ?no)
}
}
但是,此查询不会在图表中插入任何三元组。它确实删除了所有期望的三元组。根据Jena Dev列表中的Andy Seaborne(当我错误地将其标记为错误时):
?new在这一点上不在范围内 - 它不会从中流入 子查询更高。逻辑上,每个块都是独立执行的 结果将树组合在一起。 {SELECT}被执行, UNION单独执行,然后结果加入。
因此没有定义?ns因此“?ns?np?no”上的INSERT不是a 合法三重并被跳过(c.f. CONSTRUCT)。
尝试将WHERE部分作为SELECT *查询执行以查看更多信息。
这是有道理的,并且执行建议的SELECT查询是说明性的:
-----------------------------------------------------------------------------------------------------------------------------
| new | old | p | o | s | ns | no |
=============================================================================================================================
| <x-data://new> | <x-data://old> | <x-data://p> | <x-data://o1> | <x-data://old> | | <x-data://o1> |
| <x-data://new> | <x-data://old> | <x-dom://betterThan> | <x-data://old> | <x-data://new> | <x-data://new> | |
| <x-data://new> | <x-data://old> | <x-data://p> | <x-data://old> | <x-data://o0> | <x-data://o0> | |
----------------------------------------------------------------------------------------------------------------------------
鉴于此,我想重构上面的查询以提供所需的替换转换。虽然这闻到了一个常见的用例,但我还没有成功找到替换操作的现有查询。
2014年7月11日编辑
同一问题的 This Answer几乎可以满足这一要求,但需要重新构建为DELETE
- INSERT
查询。
答案 0 :(得分:1)
这是this answers.semanticweb.com answer的修改,可能适合您。我们的想法是触摸图中的每个三元组,并在它们可用时获得一个新的主题和新对象,否则保持不变。它确实有一个不幸的副作用,触摸图中的每个三元组,删除它,插入更新版本或相同的东西,所以你做了一些不必要的工作。我想你可以通过在每个可选项中绑定一个布尔值来解决这个问题(例如bind(true as ?replacedSubject)
,然后添加一个检查filter ( ?replacedSubject || ?replacedObject )
的最外层过滤器。然后你只能匹配那些三元组中的三元组。需要更换的主题或对象,你不会做无用的工作。
delete { ?s ?p ?o }
insert { ?ss ?p ?oo }
where {
?s ?p ?o
optional {
select ?s (sample(?new) as ?news) where {
?new <x-dom://betterThan> ?s
filter( !sameTerm( ?new, ?s ) )
}
group by ?s
}
optional {
select ?o (sample(?new) as ?newo) where {
?new <x-dom://betterThan> ?o
filter( !sameTerm( ?new, ?o ) )
}
group by ?o
}
bind( coalesce(?news,?s) as ?ss )
bind( coalesce(?newo,?o) as ?oo )
}