Jena/Sparql/Arq: внедрение некоторых операторов в модель во время запроса
Я построил небольшую модель RDF: она содержит только несколько троек, описывающих некоторые элементы человеческого генома.
Я хочу сохранить только те элементы, которые перекрывают некоторые геномные сегменты (скажем, "ген"), хранящиеся в другой реляционной базе данных. Эта база данных генов слишком велика, чтобы вставить ее в мою исходную модель RDF.
Есть ли способ расширить ARQ, чтобы внедрить некоторые новые операторы (операторы RDF, описывающие только гены, перекрывающие элементы) в моей модели во время запроса?
вход:
uri:object1 my:hasChromosome "chr1" .
uri:object1 my:hasStartPosition "1235689887" .
uri:object1 my:hasEndPosition "2897979879" .
uri:object1 dc:title "my variation" .
выход:
uri:object1 my:hasChromosome "chr1" .
uri:object1 my:hasStartPosition "1235689887" .
uri:object1 my:hasEndPosition "2897979879" .
uri:object1 dc:title "my variation" .
uri:gene1 dc:title "GeneName" .
Я читал о http://jena.sourceforge.net/ARQ/arq-query-eval.html но я потерян: какой механизм расширения мне выбрать? Имущество? Есть ли более полный пример в Интернете?
Спасибо,
2 ответа
У вас есть два хранилища данных. Один небольшой набор данных в модели памяти Jena и большой набор данных, связанных с генами, в реляционной базе данных. Вы хотите написать запрос sparql так, как если бы большой набор данных был локальным без фактического импорта. (Фактическое преобразование данных, которое вы хотите сделать, немного расплывчато.)
В SPARQL 1.1 вы можете сделать это, используя ключевое слово SERVICE между конечными точками sparql. Чтобы иметь возможность использовать вашу реляционную базу данных генных данных в качестве конечной точки SPARQL, вам необходим транслятор SPARQL в SQL, такой как D2RQ, или преобразовать данные в RDF и загрузить их в тройное хранилище с поддержкой SPARQL общего назначения.
Как только данные гена станут доступны в конечной точке SPARQL.
PREFIX my: <...>
PREFIX f: <java:com.example.DBFunctions.>
INSERT { ?missing a my:Gene } # mark a region as a gene
WHERE {
?missing my:hasChromosome ?chr ;
my:hasStartPosition ?start ;
my:hasEndPosition ?end .
SERVICE<http://localhost:????/gene_data/sparql>{
?gene a my:Gene .
my:hasStartPosition ?gStart ;
my:hasEndPosition ?gEnd .
#Detect overlap.
FILTER( !(?start > ?gEnd || ?end < ?gStart) ) .
}
}
Другой вариант - сделать фильтр, как показывает @user205512, с помощью пользовательской функции. Где фильтр Java-код использует JDBC для подключения к реляционной базе данных.
Детали здесь немного тонкие. Начните с простого, используя пользовательскую функцию. Это позволит вам сделать внешний поиск в FILTERs
или, используя BIND
, получить значения.
Для обновления вы можете рассмотреть возможность обновления SPARQL.
Наконец ты сказал
Я хочу сохранить только те элементы, которые перекрывают некоторые геномные сегменты (скажем, "ген"), хранящиеся в другой реляционной базе данных.
Так что, возможно, что-то вроде:
PREFIX my: <...>
PREFIX f: <java:com.example.DBFunctions.>
DELETE { ?missing ?p ?o } # Purge the non-overlapping objects
WHERE {
?missing my:hasChromosome ?chr ;
my:hasStartPosition ?start ;
my:hasEndPosition ?end .
FILTER (!f:overlaps(?chr, ?start, ?end)) # true if not overlapping
}
Хорошо, я предполагаю здесь, но я надеюсь, что это немного помогает.