我在Jena中执行SPARQL查询时遇到了困难,导致我不明白......
我试图查询Esco本体(https://ec.europa.eu/esco/download),并且我使用TDB加载本体并创建模型(对不起,如果我使用的术语不准确,我和#39;我不是很有经验)。
我的目标是在本体中找到与我之前提取的文本相匹配的工作位置:例如:提取的术语:" acuponcteur " - >本体中的标签:" Acuponcteur" @fr - > uri:< http://ec.europa.eu/esco/occupation/14918>
我称之为"奇怪的行为"与我在查询时得到(或不是)的结果有关,即:
执行以下查询时:
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX esco: <http://ec.europa.eu/esco/model#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?position
WHERE {
?s rdf:type esco:Occupation.
{ ?position skos:prefLabel ?label. }
UNION
{ ?position skos:altLabel ?label. }
FILTER (lcase(?label)= \"acuponcteur\"@fr )
}
LIMIT 10
我在1分钟后得到这些结果:
-----------------------------------------------
| position |
===============================================
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
-----------------------------------------------
但是,当我尝试添加DISTINCT关键字时,因此:
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX esco: <http://ec.europa.eu/esco/model#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?position
WHERE {
?s rdf:type esco:Occupation.
{ ?position skos:prefLabel ?label. }
UNION
{ ?position skos:altLabel ?label. }
FILTER (lcase(?label)= \"acuponcteur\"@fr )
}
LIMIT 10
似乎查询一直在运行(我在等待20分钟后停止了执行......)
我在执行与第一个查询相同的查询(因此没有DISTINCT)时会得到相同的行为,并且要匹配另一个标签,我确定不在本体中的标签。虽然期待空的结果,但它(似乎是)继续运行,我必须在一段时间后杀死它(再一次,我等了20分钟到最多):
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX esco: <http://ec.europa.eu/esco/model#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?position
WHERE {
?s rdf:type esco:Occupation.
{ ?position skos:prefLabel ?label. }
UNION
{ ?position skos:altLabel ?label. }
FILTER (lcase(?label)= \"assistante scolaire\"@fr )
}
LIMIT 10
这可能是我运行的代码中的一个问题吗?那是:
public static void main(String[] args) {
// Make a TDB-backed dataset
String directory = "data/testtdb" ;
Dataset dataset = TDBFactory.createDataset(directory) ;
// transaction (protects a TDB dataset against data corruption, unexpected process termination and system crashes)
dataset.begin( ReadWrite.WRITE );
// assume we want the default model, or we could get a named model here
Model model = dataset.getDefaultModel();
try {
// read the input file - only needs to be done once
String source = "data/esco.rdf";
FileManager.get().readModel(model, source, "RDF/XML-ABBREV");
// run a query
String queryString =
"PREFIX skos: <http://www.w3.org/2004/02/skos/core#> " +
"PREFIX esco: <http://ec.europa.eu/esco/model#> " +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
"SELECT ?position " +
"WHERE { " +
" ?s rdf:type esco:Occupation. " +
" { ?position skos:prefLabel ?label. } " +
" UNION " +
" { ?position skos:altLabel ?label. }" +
" FILTER (lcase(?label)= \"acuponcteur\"@fr ) " +
"}" +
"LIMIT 1 " ;
Query query = QueryFactory.create(queryString) ;
// execute the query
QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
try {
ResultSet results = qexec.execSelect() ;
// taken from apache Jena tutorial
ResultSetFormatter.out(System.out, results, query) ;
} finally {
qexec.close() ;
}
} finally {
model.close() ;
dataset.end();
}
}
我在这里做错了什么?有什么想法吗?
谢谢!
答案 0 :(得分:6)
作为可能会或可能没有太大区别的第一点,您可以使用属性路径来简化
{ ?position skos:prefLabel ?label. }
UNION
{ ?position skos:altLabel ?label. }
as
?position skos:prefLabel|skos:altLabel ?label
这使得查询:
SELECT ?position
WHERE {
?s rdf:type esco:Occupation. # (1)
?position skos:prefLabel|skos:altLabel ?label # (2)
FILTER (lcase(?label)="acuponcteur"@fr )
}
这个查询有什么意义?有一些 n 的?位置/?标签对匹配(2),有些数字 m 的值匹配(1)。从查询中获得的结果数是 m×n ,但您从不使用?s的值。看起来你使用DISTINCT来摆脱一些重复的值,但是你没有看到为什么你首先得到重复的值。您应该只删除无用的行(1),并具有查询:
SELECT DISTINCT ?position
WHERE {
?position skos:prefLabel|skos:altLabel ?label
FILTER (lcase(?label)="acuponcteur"@fr )
}
如果您不再需要DISTINCT,我不会感到惊讶。