Можно ли использовать вложенное удаление в запросах SPARQL?
Я хотел бы использовать запрос для дедупликации ресурсов с использованием уникального идентификатора. Запрос вставки / удаления не работает, потому что нужно создать меньше узлов, чем удалено. Можно ли использовать что-то похожее на это?
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
}
}
}
1 ответ
Просто "потому что нужно создать меньше узлов, чем удалено", не обязательно означает, что вы не можете использовать обычные операции вставки / удаления. 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)
}
Если вы пытаетесь объединить все учетные записи в одну, даже если они имеют разные идентификаторы, вы можете просто передать постоянное значение в функцию bnode, например,
bind (bnode("") as ?new)