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

Is it possible to use a nested delete in SPARQL queries?

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

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

只是"because less nodes have to be created than are deleted"并不一定意味着你不能使用普通的insert/delete。 RDF 是一种基于集合的表示;如果多次插入相同的三元组,则与插入一次相同。如果你想标准化一堆三元组,你可以通过使用 bnode 和一个参数来为查询结果创建相同的空白节点:(强调):

The BNODE function constructs a blank node that is distinct from all blank nodes in the dataset being queried and distinct from all blank nodes created by calls to this constructor for other query solutions. If the no argument form is used, every call results in a distinct blank node. If the form with a simple literal is used, every call results in distinct blank nodes for different simple literals, and the same blank node for calls with the same simple literal within expressions for one solution mapping.

这意味着您可以:

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)