3

我有一个数据集,其中我试图用另一个人替换符合某些条件的个人。在提供的最小示例中,我希望x-data://oldx-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 不是合法的三元组,因此被跳过(参见 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 to the same question几乎可以满足这一点,但需要重组为DELETE-INSERT查询的形式。

4

1 回答 1

1

这是对此 answers.semanticweb.com 答案的修改,可能对您有用。这个想法是触摸图中的每一个三元组,并在它们可用时为其获取一个新的主题和新的对象,否则保持它们不变。它确实具有触摸图表中的每个三元组、删除它并插入更新版本或相同内容的不幸副作用,因此您正在做一些不必要的工作。我想你可以通过在每个可选中绑定一个布尔值来解决这个问题(例如,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 )
}
于 2014-07-11T15:54:35.903 回答