使用Sparql创建URI的最佳方法(例如自动递增)

时间:2019-04-11 15:10:11

标签: sparql rdf

我目前正在编写一项通过用户输入创建新项目(数据)的服务。要将这些项目保存在RDF图形存储中(当前通过Sparql 1.1使用Sesame),我需要在数据中添加一个主题URI。我的方法是为每个新项目使用递增的数字。例如:

abstract class ClassA {
    <T extends ItemA> void setValues(T item) {
    item.setValueA("valueA");
        getValues(item);
    }
    abstract void getValues(MainItem item);
}

通过Sparql为新项目(如MySQL / MongoDB中的自动增加)获取递增编号的最佳方法是什么?或发布一些数据,端点通过模板自动创建URI(就像对空白节点所做的那样)。 但是我不想将空白节点用作这些项目的主题。 有没有比使用递增数字更好的解决方案?我的用户不在乎URI...。我不想处理诸如通过对数据进行哈希处理并将哈希值用作主题的一部分而造成的冲突。

3 个答案:

答案 0 :(得分:2)

假设您的商品类别为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)
    }
}

(使用RDDB4J 2.2.2在GraphDB 8.4.0中进行了测试)

答案 1 :(得分:2)

如果您在更新期间维护了一个指定的计数器,那么遵循这些原则即可做到

fisrt在您的数据集中插入一个计数器

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

答案 2 :(得分:1)

您说过,除了自动递增的数字之外,您还可以选择其他选项。一种不错的选择是使用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标准的一部分。唯一的缺点是它们又长又丑。