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

Rdf 如何为重命名操作生成统一绑定,rdf,sparql,jena,arq,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://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> .
所需输出数据集的示例:

<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开发列表上的Andy Seaborne,当我错误地将其标记为bug时:

?此时新的不在范围内-它不会从 向上的子查询。从逻辑上讲,每个块都是独立执行的 结果将树合并起来。执行{SELECT}时 UNION单独执行,然后将结果合并

因此?ns没有定义,因此?ns?np?no上的插入不是 合法三元组和跳过c.f.构造

尝试将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日编辑

对同一个问题的处理几乎满足了这一点,但需要重新构造为DELETE-INSERT查询的形式。

这里有一个可能适合您的修改。我们的想法是触摸图形中的每一个三元组,并在它们可用时为其获取一个新的主题和对象,但在其他情况下保持不变。它确实有一个不幸的副作用,即触摸图形中的每一个三元组,删除它,然后插入更新版本或相同的内容,因此您正在做一些不必要的工作。我想您可以通过在每个可选项中绑定一个布尔值来解决这个问题,例如bindtrue作为?replacedSubject,然后添加一个最外层的过滤器来检查filter?replacedSubject | | replacedbject。然后你只需要匹配那些需要替换主体或对象的三元组,你就不会做无用的工作了

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

在子选择中匹配新旧的目的是什么?这仅仅是为了把自己限制在一个结果上吗?例如,你为什么不能只用?新的:比旧的更好。{…}联合{…}?Andy的回答提到可以组合多个操作。我想知道这种技术是否可以在这里应用……好吧,但是如果不止一个:比三倍更好,你怎么知道你得到了你想要的呢?目前您的子选择中没有订购条件或任何内容…您确定吗?如果你有3>2。2>1,其中>是:比你先选择2>1更好,然后你不用2>2替换2>1,然后你就可以无休止地在2>2上迭代了吗?作为一个很可能性能很差的选项,你能不能把另外两个查询也作为子选择来执行,从而在你选择的第一个子选择上加入旧的和新的?