SPARQL эквивалент SQL-запроса выбора?
Если у меня есть таблица SQL, которую можно запросить так:
Select empname from mytable
Where empid=1;
Каким будет эквивалентный запрос SPARQL?
1 ответ
Как несколько человек упоминали здесь и на вашем подобном предыдущем вопросе, вам, вероятно, нужно еще немного прочесть о природе данных, смоделированных RDF.
Для переполнения стека вам определенно нужно привыкнуть показывать свои входные данные и любой код, который вы написали до сих пор, даже если он не работает идеально. В этом случае вам нужно включить сообщение об ошибке в ваш вопрос.
Вот отдельный пример, в котором я
- угадал, как выглядит твой стол
- смоделировал это как RDF
- написал запрос SPARQL, который делает то, что вы просили
Пример написан на R, мой самый сильный язык. Чтобы быть ясным: вам не нужно ничего знать о R, чтобы хорошо разбираться в RDF, SPARQL и других семантических технологиях. Если бы я был лучше в Java или Python, я написал бы пример на одном из этих языков.
Реляционные (SQL) данные должны быть преобразованы в RDF, прежде чем их можно будет запросить с помощью RDF. В приведенном ниже коде я сделал это вручную. Смотрите конец сообщения для гаек и болтов.
library(rrdf)
library(sqldf)
mytable.table.string <- 'empid,empname
1,Arthur
2,Kevin
3,Joey'
mytable <- read.csv(textConnection(mytable.table.string))
print(mytable)
> empid empname
> 1 1 Arthur
> 2 2 Kevin
> 3 3 Joey
sqldf('select empname from mytable where empid = 1')
> empname
> 1 Arthur
# R2RML conversion goes here
# I did it by hand
table.rdf.string <- 'prefix mytable: <http://mytable/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
mytable:1 a mytable:employee .
mytable:1 mytable:empid "1" .
mytable:1 rdfs:label "Arthur" .
mytable:2 a mytable:employee .
mytable:2 mytable:empid "2" .
mytable:2 rdfs:label "Kevin" .
mytable:3 a mytable:employee .
mytable:3 mytable:empid "3" .
mytable:3 rdfs:label "Joey" . '
mytable.rdf <- fromString.rdf(table.rdf.string, format = "TURTLE")
query.as.sparql <- 'prefix mytable: <http://mytable/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?empname
where
{?emp a mytable:employee .
?emp mytable:empid "1" .
?emp rdfs:label ?empname . }'
sparql.rdf(model = mytable.rdf, sparql = query.as.sparql)
> empname
> [1,] "Arthur"
Чтобы просмотреть: этот код R выше демонстрирует запрос SAPRQL, который эквивалентен SQL-запросу OP. SQL-запросы обычно выполняются с базами данных SQL, но я сделал это самодостаточным, запустив его на базе данных.
Запросы SPARQL выполняются для данных RDF, часто в форме базы данных тройного хранилища. В моем примере строка, содержащая тройки RDF, преобразуется в модель RDF в памяти, и запрос SPARQL отправляется этой модели.
Таким образом, возникает вопрос: если у вас есть данные в базе данных SQL, как вы запрашиваете содержимое базы данных с помощью SPARQL? По состоянию на лето 2017 года эта тема постоянно развивается. Существует множество коммерческих инструментов и инструментов с открытым исходным кодом, которые могут помочь решить эту проблему, обычно одним из двух способов:
- создавая интерфейс для отправки запроса SPARQL непосредственно в базу данных SQL в режиме реального времени
- путем преобразования и выгрузки содержимого базы данных SQL в виде статического файла RDF, который затем может быть загружен в наивное SPARQL-совместимое хранилище триплетов
В любом случае кому-то понадобится создать отображение из данных SQL в формат RDF. Это необходимо, потому что таблицы SQL не имеют явной семантики. Строки обычно моделируют людей определенной категории, а столбцы обычно представляют свойства или отношения людей. RDF-тройки должны иметь явную семантику субъект-глагол-объект.
Вот мои рекомендуемые первые шаги для отображения SQL-RDF с помощью Karma, который имеет приятный графический интерфейс. Аналогичные результаты могут быть достигнуты с другим сопоставителем R2RML, таким как D2RQ (работает, но не поддерживается в течение 3 лет), ontop или анализатором R2RML.
- Посмотрите видео о Карме и прочитайте руководство пользователя, особенно шаги 1 - 5 плюс 7.
- Установите Карму в соответствии с опубликованными инструкциями.
- Запустить Карму. Веб-интерфейс для кармы должен появиться в вашем веб-браузере
- Вставьте приведенную ниже онтологию в текстовый редактор и сохраните как
44403425.owl
Откройте прилагаемую онтологию в Карме (import
->from file
) - Кроме того, сохранить и импортировать
mytable.csv
, который предназначен для представления дампа из базы данных SQL. Если вы хотите работать с действующей базой данных, вы должны будете убедиться, что установлены правильные драйверы базы данных. В этом случае используйтеimport
->Database Table
вместо. - Опять же, сохраните модель как
mytable-model.ttl
, Нажмите на раскрывающийся список слева от серой панели в верхней части веб-страницы Кармы. выберитеApply R2RML model
->from file
и загрузитьmytable_model.ttl
- Снова нажмите на выпадающий список и выберите
Publish
->RDF
, Примите предложенные настройки. - Ищу
OpenRDF
справа сверху черная полоса. Щелкните правой кнопкой мыши по этой ссылке, чтобы открыть ее в новом окне / вкладке браузера. - На странице OpenRDF Workbench выберите
karma_data
репозиторий. Теперь вы можете использовать любой изExplore
ссылки слева, включая (SPARQL)Query
ссылка на сайт - Страница OpenRDF Workbench станет недоступной, когда вы закроете Karma. Вы можете экспортировать свои новые тройки из OpenRDF Workbench, или вы можете сделать это из серой панели в Карме. Вы также можете экспортировать файл моделирования, если вы внесли в него какие-либо изменения. В этот момент тройки данных RDF могут быть загружены в любое другое хранилище триплетов или исследованы с помощью инструментов командной строки, таких как ARQ от Jena.
Наконец, если вы хотите использовать сопоставитель R2RML, отличный от Karma, вы можете использовать файл сопоставления, аналогичный (но не идентичный) mytable-model.ttl
, Карма выполняет некоторые манипуляции с данными с помощью фрагментов Python, которые встраиваются в JSON. Этот JSON становится огромным объектом km-dev:hasWorksheetHistory
тройная. Я не верю, что все парсеры R2RML распознают Python / JSON.
44403425.owl
<?xml version="1.0"?>
<rdf:RDF xmlns="https://stackru.com/questions/44403425.owl/"
xml:base="https://stackru.com/questions/44403425.owl/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:mytable="https://stackru.com/questions/44403425.owl/"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="https://stackru.com/questions/44403425.owl"/>
<owl:DatatypeProperty rdf:about="https://stackru.com/questions/44403425.owl/empid">
<rdfs:domain rdf:resource="https://stackru.com/questions/44403425.owl/employee"/>
<rdfs:range rdf:resource="http://www.w3.org/2000/01/rdf-schema#Literal"/>
<rdfs:label>employee identifier</rdfs:label>
</owl:DatatypeProperty>
<owl:Class rdf:about="https://stackru.com/questions/44403425.owl/employee">
<owl:equivalentClass>
<owl:Restriction>
<owl:onProperty rdf:resource="https://stackru.com/questions/44403425.owl/empid"/>
<owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</owl:equivalentClass>
<rdfs:label>employee class</rdfs:label>
</owl:Class>
</rdf:RDF>
mytable.csv
"empid","empname"
1,"Arthur"
2,"Kevin"
3,"Joey"
туЬаЫе-model.ttl
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix pato: <http://purl.obolibrary.org/obo/pato#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix obo: <http://purl.obolibrary.org/obo/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix oboInOwl: <http://www.geneontology.org/formats/oboInOwl#> .
@prefix protege: <http://protege.stanford.edu/plugins/owl/protege#> .
@prefix turbo: <http://turbo.org/> .
@prefix subsets: <http://purl.obolibrary.org/obo/ro/subsets#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rr: <http://www.w3.org/ns/r2rml#> .
@prefix km-dev: <http://isi.edu/integration/karma/dev#> .
_:node1bi2073ftx1 a km-dev:R2RMLMapping ;
km-dev:sourceName "mytable.csv" ;
km-dev:modelPublicationTime "1496863444477"^^xsd:long ;
km-dev:modelVersion "1.7" ;
km-dev:hasInputColumns "[[{\"columnName\":\"empname\"}],[{\"columnName\":\"empid\"}]]" ;
km-dev:hasOutputColumns "[[{\"columnName\":\"empname\"}],[{\"columnName\":\"empid\"}],[{\"columnName\":\"empid_val\"}]]" ;
km-dev:hasModelLabel "mytable" ;
km-dev:hasBaseURI "https://stackru.com/questions/44403425.owl/" ;
km-dev:hasWorksheetHistory """[
{
\"commandName\": \"SubmitPythonTransformationCommand\",
\"model\": \"new\",
\"inputParameters\": [
{
\"name\": \"hNodeId\",
\"type\": \"hNodeId\",
\"value\": [{\"columnName\": \"empid\"}]
},
{
\"name\": \"worksheetId\",
\"type\": \"worksheetId\",
\"value\": \"W\"
},
{
\"name\": \"selectionName\",
\"type\": \"other\",
\"value\": \"DEFAULT_TEST\"
},
{
\"name\": \"newColumnName\",
\"type\": \"other\",
\"value\": \"empid_val\"
},
{
\"name\": \"transformationCode\",
\"type\": \"other\",
\"value\": \"return getValue(\\\"empid\\\")\"
},
{
\"name\": \"errorDefaultValue\",
\"type\": \"other\",
\"value\": \"\"
},
{
\"name\": \"isJSONOutput\",
\"type\": \"other\",
\"value\": \"false\"
},
{
\"name\": \"inputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[{\\\"value\\\":[{\\\"columnName\\\":\\\"empid\\\"}]}]\"
},
{
\"name\": \"outputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[{\\\"value\\\":[{\\\"columnName\\\":\\\"empid_val\\\"}]}]\"
}
],
\"tags\": [\"Transformation\"]
},
{
\"commandName\": \"SetWorksheetPropertiesCommand\",
\"model\": \"new\",
\"inputParameters\": [
{
\"name\": \"worksheetId\",
\"type\": \"worksheetId\",
\"value\": \"W\"
},
{
\"name\": \"selectionName\",
\"type\": \"other\",
\"value\": \"DEFAULT_TEST\"
},
{
\"name\": \"properties\",
\"type\": \"other\",
\"value\": {
\"graphLabel\": \"\",
\"hasBaseURI\": false,
\"prefix\": \"mytable\",
\"hasPrefix\": true,
\"hasServiceProperties\": false
}
},
{
\"name\": \"inputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[]\"
},
{
\"name\": \"outputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[]\"
}
],
\"tags\": [\"Transformation\"]
},
{
\"commandName\": \"SetWorksheetPropertiesCommand\",
\"model\": \"new\",
\"inputParameters\": [
{
\"name\": \"worksheetId\",
\"type\": \"worksheetId\",
\"value\": \"W\"
},
{
\"name\": \"selectionName\",
\"type\": \"other\",
\"value\": \"DEFAULT_TEST\"
},
{
\"name\": \"properties\",
\"type\": \"other\",
\"value\": {
\"graphLabel\": \"\",
\"hasBaseURI\": true,
\"baseURI\": \"https://stackru.com/questions/44403425.owl/\",
\"hasPrefix\": false,
\"hasServiceProperties\": false
}
},
{
\"name\": \"inputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[]\"
},
{
\"name\": \"outputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[]\"
}
],
\"tags\": [\"Transformation\"]
},
{
\"commandName\": \"SetWorksheetPropertiesCommand\",
\"model\": \"new\",
\"inputParameters\": [
{
\"name\": \"worksheetId\",
\"type\": \"worksheetId\",
\"value\": \"W\"
},
{
\"name\": \"selectionName\",
\"type\": \"other\",
\"value\": \"DEFAULT_TEST\"
},
{
\"name\": \"properties\",
\"type\": \"other\",
\"value\": {
\"graphLabel\": \"mytable\",
\"hasBaseURI\": false,
\"hasPrefix\": false,
\"hasServiceProperties\": false
}
},
{
\"name\": \"inputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[]\"
},
{
\"name\": \"outputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[]\"
}
],
\"tags\": [\"Transformation\"]
},
{
\"commandName\": \"SetMetaPropertyCommand\",
\"model\": \"new\",
\"inputParameters\": [
{
\"name\": \"hNodeId\",
\"type\": \"hNodeId\",
\"value\": [{\"columnName\": \"empid\"}]
},
{
\"name\": \"worksheetId\",
\"type\": \"worksheetId\",
\"value\": \"W\"
},
{
\"name\": \"selectionName\",
\"type\": \"other\",
\"value\": \"DEFAULT_TEST\"
},
{
\"name\": \"metaPropertyName\",
\"type\": \"other\",
\"value\": \"isUriOfClass\"
},
{
\"name\": \"metaPropertyUri\",
\"type\": \"other\",
\"value\": \"https://stackru.com/questions/44403425.owl/employee\"
},
{
\"name\": \"metaPropertyId\",
\"type\": \"other\",
\"value\": \"https://stackru.com/questions/44403425.owl/employee1\"
},
{
\"name\": \"SemanticTypesArray\",
\"type\": \"other\",
\"value\": [{
\"DomainUri\": \"https://stackru.com/questions/44403425.owl/employee\",
\"DomainId\": \"https://stackru.com/questions/44403425.owl/employee1\",
\"isPrimary\": true,
\"isProvenance\": false,
\"FullType\": \"http://isi.edu/integration/karma/dev#classLink\",
\"DomainLabel\": \"https://stackru.com/questions/44403425.owl/employee/employee1 (add)\"
}]
},
{
\"name\": \"trainAndShowUpdates\",
\"type\": \"other\",
\"value\": true
},
{
\"name\": \"rdfLiteralType\",
\"type\": \"other\",
\"value\": \"\"
},
{
\"name\": \"language\",
\"type\": \"other\",
\"value\": \"\"
},
{
\"name\": \"inputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[{\\\"value\\\":[{\\\"columnName\\\":\\\"empid\\\"}]}]\"
},
{
\"name\": \"outputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[{\\\"value\\\":[{\\\"columnName\\\":\\\"empid\\\"}]}]\"
}
],
\"tags\": [\"SemanticType\"]
},
{
\"commandName\": \"SetSemanticTypeCommand\",
\"model\": \"new\",
\"inputParameters\": [
{
\"name\": \"hNodeId\",
\"type\": \"hNodeId\",
\"value\": [{\"columnName\": \"empid_val\"}]
},
{
\"name\": \"worksheetId\",
\"type\": \"worksheetId\",
\"value\": \"W\"
},
{
\"name\": \"selectionName\",
\"type\": \"other\",
\"value\": \"DEFAULT_TEST\"
},
{
\"name\": \"SemanticTypesArray\",
\"type\": \"other\",
\"value\": [{
\"DomainUri\": \"https://stackru.com/questions/44403425.owl/employee\",
\"DomainId\": \"https://stackru.com/questions/44403425.owl/employee1\",
\"isPrimary\": true,
\"isProvenance\": false,
\"FullType\": \"https://stackru.com/questions/44403425.owl/empid\",
\"DomainLabel\": \"https://stackru.com/questions/44403425.owl/employee/employee1\"
}]
},
{
\"name\": \"trainAndShowUpdates\",
\"type\": \"other\",
\"value\": true
},
{
\"name\": \"rdfLiteralType\",
\"type\": \"other\",
\"value\": \"\"
},
{
\"name\": \"language\",
\"type\": \"other\",
\"value\": \"\"
},
{
\"name\": \"inputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[{\\\"value\\\":[{\\\"columnName\\\":\\\"empid_val\\\"}]}]\"
},
{
\"name\": \"outputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[{\\\"value\\\":[{\\\"columnName\\\":\\\"empid_val\\\"}]}]\"
}
],
\"tags\": [\"SemanticType\"]
},
{
\"commandName\": \"SetSemanticTypeCommand\",
\"model\": \"new\",
\"inputParameters\": [
{
\"name\": \"hNodeId\",
\"type\": \"hNodeId\",
\"value\": [{\"columnName\": \"empname\"}]
},
{
\"name\": \"worksheetId\",
\"type\": \"worksheetId\",
\"value\": \"W\"
},
{
\"name\": \"selectionName\",
\"type\": \"other\",
\"value\": \"DEFAULT_TEST\"
},
{
\"name\": \"SemanticTypesArray\",
\"type\": \"other\",
\"value\": [{
\"DomainUri\": \"https://stackru.com/questions/44403425.owl/employee\",
\"DomainId\": \"https://stackru.com/questions/44403425.owl/employee1\",
\"isPrimary\": true,
\"isProvenance\": false,
\"FullType\": \"http://www.w3.org/2000/01/rdf-schema#label\",
\"DomainLabel\": \"https://stackru.com/questions/44403425.owl/employee/employee1\"
}]
},
{
\"name\": \"trainAndShowUpdates\",
\"type\": \"other\",
\"value\": true
},
{
\"name\": \"rdfLiteralType\",
\"type\": \"other\",
\"value\": \"\"
},
{
\"name\": \"language\",
\"type\": \"other\",
\"value\": \"\"
},
{
\"name\": \"inputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[{\\\"value\\\":[{\\\"columnName\\\":\\\"empname\\\"}]}]\"
},
{
\"name\": \"outputColumns\",
\"type\": \"hNodeIdList\",
\"value\": \"[{\\\"value\\\":[{\\\"columnName\\\":\\\"empname\\\"}]}]\"
}
],
\"tags\": [\"SemanticType\"]
}
]""" .
km-dev:TriplesMap_d397eb02-1069-4e93-a544-0f2c4d1f8970 a rr:TriplesMap .
_:node1bi2073ftx1 km-dev:hasTriplesMap km-dev:TriplesMap_d397eb02-1069-4e93-a544-0f2c4d1f8970 .
km-dev:TriplesMap_d397eb02-1069-4e93-a544-0f2c4d1f8970 km-dev:isPartOfMapping _:node1bi2073ftx1 .
_:node1bi2073ftx2 rr:tableName "mytable.csv" ;
a rr:LogicalTable ;
km-dev:isPartOfMapping _:node1bi2073ftx1 .
_:node1bi2073ftx1 km-dev:hasLogicalTable _:node1bi2073ftx2 .
km-dev:TriplesMap_d397eb02-1069-4e93-a544-0f2c4d1f8970 rr:logicalTable _:node1bi2073ftx2 ;
rr:subjectMap _:node1bi2073ftx3 .
_:node1bi2073ftx1 km-dev:hasSubjectMap _:node1bi2073ftx3 .
_:node1bi2073ftx3 km-dev:isPartOfMapping _:node1bi2073ftx1 ;
a rr:SubjectMap ;
km-dev:alignmentNodeId "https://stackru.com/questions/44403425.owl/employee1" ;
rr:class <https://stackru.com/questions/44403425.owl/employee> ;
rr:template "{empid}" ;
a km-dev:steinerTreeRootNode .
km-dev:PredicateObjectMap_5a63b356-1bbb-4b1f-b64a-514c19f83d28 rr:predicate <https://stackru.com/questions/44403425.owl/empid> .
_:node1bi2073ftx4 rr:column "empid" ;
a rr:ObjectMap ;
km-dev:isPartOfMapping _:node1bi2073ftx1 .
_:node1bi2073ftx1 km-dev:hasObjectMap _:node1bi2073ftx4 .
km-dev:PredicateObjectMap_5a63b356-1bbb-4b1f-b64a-514c19f83d28 rr:objectMap _:node1bi2073ftx4 .
km-dev:TriplesMap_d397eb02-1069-4e93-a544-0f2c4d1f8970 rr:predicateObjectMap km-dev:PredicateObjectMap_5a63b356-1bbb-4b1f-b64a-514c19f83d28 .
km-dev:PredicateObjectMap_5a63b356-1bbb-4b1f-b64a-514c19f83d28 a rr:PredicateObjectMap ;
km-dev:isPartOfMapping _:node1bi2073ftx1 .
_:node1bi2073ftx1 km-dev:hasPredicateObjectMap km-dev:PredicateObjectMap_5a63b356-1bbb-4b1f-b64a-514c19f83d28 .
km-dev:PredicateObjectMap_028e84af-9ed2-406c-81d0-9add2ed2ca2b rr:predicate rdfs:label .
_:node1bi2073ftx5 rr:column "empname" ;
a rr:ObjectMap ;
km-dev:isPartOfMapping _:node1bi2073ftx1 .
_:node1bi2073ftx1 km-dev:hasObjectMap _:node1bi2073ftx5 .
km-dev:PredicateObjectMap_028e84af-9ed2-406c-81d0-9add2ed2ca2b rr:objectMap _:node1bi2073ftx5 .
km-dev:TriplesMap_d397eb02-1069-4e93-a544-0f2c4d1f8970 rr:predicateObjectMap km-dev:PredicateObjectMap_028e84af-9ed2-406c-81d0-9add2ed2ca2b .
km-dev:PredicateObjectMap_028e84af-9ed2-406c-81d0-9add2ed2ca2b a rr:PredicateObjectMap ;
km-dev:isPartOfMapping _:node1bi2073ftx1 .
_:node1bi2073ftx1 km-dev:hasPredicateObjectMap km-dev:PredicateObjectMap_028e84af-9ed2-406c-81d0-9add2ed2ca2b .