Лучший подход для создания URI с помощью Sparql (например, автоинкремент) - PullRequest
3 голосов
/ 11 апреля 2019

В настоящее время я пишу сервис, который создает новые элементы (данные) путем ввода данных пользователем.Чтобы сохранить эти элементы в RDF Graph Store (в настоящее время использующем Sesame через Sparql 1.1), мне нужно добавить в данные URI субъекта.Мой подход заключается в использовании числа, которое увеличивается для каждого нового элемента.Например:

<http://example.org/item/15> dct:title "Example Title" .
<http://example.org/item/16> dct:title "Other Item" .

Каков наилучший подход для получения увеличенного числа для новых элементов (например, автоматического ввода в MySQL / MongoDB) через Sparql?Или выдать некоторые данные, и конечная точка автоматически создаст URI по шаблону (как это делается для пустых узлов).Но я не хочу использовать пустые узлы в качестве предметов для этих предметов.Есть ли лучшее решение, чем использование увеличенного числа?Моим пользователям нет дела до URI .... и я не хочу обрабатывать коллизии, подобные тем, которые были созданы путем хеширования данных и использования хеша как части темы.

Ответы [ 3 ]

3 голосов
/ 12 апреля 2019

Если вы сохраняете назначенный счетчик во время обновлений, то что-то вроде этого будет делать,

Сначала вставьте счетчик в ваш набор данных

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 голосов
/ 11 апреля 2019

Если предположить, что класс ваших предметов равен 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)
    }
}

(протестировано с GraphDB 8.4.0 с использованием RDF4J 2.2.2)

1 голос
/ 11 апреля 2019

Вы сказали, что открыты для других опций, кроме автоматического увеличения числа. Хорошей альтернативой является использование UUIDs .

Если вам все равно, как выглядит URI, вы можете использовать функцию UUID:

INSERT {
    ?uri dct:title "Example Title"
}
WHERE {
    BIND (UUID() AS ?uri)
}

Это создаст URI, такие как <urn:uuid:b9302fb5-642e-4d3b-af19-29a8f6d894c9>.

Если вы предпочитаете иметь HTTP URI в своем собственном пространстве имен, вы можете использовать strUUID:

INSERT {
    ?uri dct:title "Example Title"
}
WHERE {
    BIND (IRI(CONCAT("http://example.org/item/", strUUID())) AS ?uri)
}

Это создаст URI, такие как http://example.org/item/73cd4307-8a99-4691-a608-b5bda64fb6c1.

UUID довольно хороши. Риск столкновения незначителен. Функции являются частью стандарта SPARQL. Единственный недостаток в том, что они длинные и некрасивые.

...