是否可以在SPARQL查询中使用嵌套删除



我想使用一个查询来使用一个唯一的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
}
}
}

仅仅"因为创建的节点比删除的节点少"并不一定意味着不能使用普通的插入/删除。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)