如何为重命名操作生成统一绑定

时间:2014-04-10 20:44:34

标签: rdf sparql jena arq

我有一个数据集,其中我试图将符合某些条件的个人替换为另一个人。在提供的最小示例中,我希望将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查询。

1 个答案:

答案 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 )
}