我目前正在编写一个通过用户输入创建新项目(数据)的服务。要将这些项目保存在RDF图形存储中(当前通过Sparql 1.1使用Sesame),我需要向数据添加主题URI。我的方法是使用为每个新项目递增的数字。例如:
<http://example.org/item/15> dct:title "Example Title" .
<http://example.org/item/16> dct:title "Other Item" .
通过Sparql获取新项目(例如MySQL / MongoDB中的自动入侵)的增加数字的最佳方法是什么?或者发布一些数据,端点通过模板自动创建URI(就像为空白节点完成)。但我不想使用空白节点作为这些项目的主题。有没有比使用递增数字更好的解决方案?我的用户不关心URI ....我不想处理像散列数据和使用散列作为主题的一部分创建的冲突。
如果您在更新期间维护一个指定的计数器,那么沿着这些方向会做的事情,
首先在您的数据集中插入一个计数器
insert data {
graph <urn:counters> {<urn:Example> <urn:count> 1 }
}
那么典型的更新应该是这样的:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
delete {
#remove the old value of the counter
graph <urn:counters> {<urn:Example> <urn:count> ?old}
}
insert {
#update the new value of the counter
graph <urn:counters> {<urn:Example> <urn:count> ?new}
# add your new data using the constructed IRI
GRAPH <http://example.com> {
?id dct:title "Example Title" ;
a <http://example.org/ontology/Example> .
} .
} where {
# retrieve the counter
graph <urn:counters> {<urn:Example> <urn:count> ?old}
# compute the new value
bind(?old+1 as ?new)
#construct the IRI
bind(IRI(concat("http://example.org/item/", str(?old))) as ?id)
}
假设您的项目类为http://example.org/ontology/Example
,则查询将变为以下内容。注意:必须逐个插入项目,因为每个事务只计算一个新的URI。
PREFIX dct: <http://purl.org/dc/terms/>
INSERT {
GRAPH <http://example.com> {
?id dct:title "Example Title" ;
a <http://example.org/ontology/Example> .
} .
} WHERE {
SELECT ?id WHERE {
{
SELECT (count(*) AS ?c) WHERE {
GRAPH <http://example.com> { ?s a <http://example.org/ontology/Example> }
}
}
BIND(IRI(CONCAT("http://example.org/item/", STR(?c))) AS ?id)
}
}
(使用RDF4J 2.2.2测试GraphDB 8.4.0)
你说你对其他选项比对自动递增的数字更开放。一个很好的选择是使用UUIDs。
如果您根本不关心URI的样子,可以使用UUID
函数:
INSERT {
?uri dct:title "Example Title"
}
WHERE {
BIND (UUID() AS ?uri)
}
这将生成像<urn:uuid:b9302fb5-642e-4d3b-af19-29a8f6d894c9>
这样的URI。
如果您更愿意在自己的命名空间中使用HTTP URI,则可以使用strUUID
:
INSERT {
?uri dct:title "Example Title"
}
WHERE {
BIND (IRI(CONCAT("http://example.org/item/", strUUID())) AS ?uri)
}
这将生成像http://example.org/item/73cd4307-8a99-4691-a608-b5bda64fb6c1
这样的URI。
UUID非常好。碰撞风险可以忽略不计。这些函数是SPARQL标准的一部分。唯一的缺点是他们长而丑陋。