1

我想使用查询来使用唯一 ID 对资源进行重复数据删除。插入/删除 - 查询不起作用,因为创建的节点比删除的节点少。是否可以使用类似的东西?

insert {
    ?new a mails:Account.
    ?new mails:hasID ?id.
    ?new rdfs:label ?label
  }
where {
    {
        select distinct ?id ?label where {
            ?account a mails:Account.
            ?account mails:hasID ?id.
            ?account rdfs:label ?label
        }
    }
    bind(bnode() as ?new)
    {
        delete where {
            ?account mails:hasID ?id
        }
    }
}
4

1 回答 1

1

只是“因为必须创建的节点少于删除的节点”并不一定意味着您不能使用正常的插入/删除。RDF 是基于集合的表示;如果多次插入相同的三元组,则与插入一次相同。如果你想标准化一堆三元组,你可以通过使用带有参数的bnode为查询结果创建相同的空白节点:(添加了重点):

BNODE函数构造一个空白节点,该节点与正在查询的数据集中的所有空白节点不同,也不同于通过调用此构造函数为其他查询解决方案创建的所有空白节点。如果使用无参数形式,则每次调用都会产生一个不同的空白节点。如果使用具有简单文字的表单,则每次调用都会为不同的简单文字生成不同的空白节点,而对于一个解决方案映射的表达式中具有相同简单文字的调用,则会产生相同的空白节点。

这意味着您可以执行以下操作:

insert {
  ?new a mails:Account.
  ?new mails:hasID ?id.
  ?new rdfs:label ?label
}
delete {
  ?account mails:hasId ?id
}
where {
  ?account a mails:Account.
  ?account mails:hasID ?id.
  ?account rdfs:label ?label

  #-- One new bnode is created for each *distinct*
  #-- ?id value.  If two accounts have the same 
  #-- ?id value, then they will get the same bnode().
  bind (bnode(str(?id)) as ?new)
}

如果您尝试将所有帐户合并为一个,即使它们具有不同的 ID,您也可以将一个常量值传递给bnode函数,例如,

bind (bnode("") as ?new)
于 2016-05-24T12:44:33.540 回答