【问题标题】:Sparql query running foreverSparql 查询永远运行
【发布时间】:2014-08-14 09:32:40
【问题描述】:

我正在努力在 Jena 中执行 SPARQL 查询,结果导致我不理解的行为...

我正在尝试查询 Esco 本体 (https://ec.europa.eu/esco/download),我正在使用 TDB 加载本体并创建模型(对不起,如果我使用的术语不准确,我不是很有经验) .

我的目标是在本体中找到一个与我之前提取的文本匹配的职位 uri:例如:提取的术语:“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();
      }

}

我在这里做错了什么?有什么想法吗?

谢谢!

【问题讨论】:

    标签: java sparql jena tdb


    【解决方案1】:

    作为第一点,可能会或可能不会有太大区别,您可以使用属性路径来简化

    { ?position skos:prefLabel ?label. } 
    UNION 
    { ?position skos:altLabel ?label. } 
    

    作为

    ?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 ) 
    }
    

    这个查询中 ?s 的意义何在?有一些 n 个 ?position/?label 对匹配 (2),以及一些 m 个 ?s 值匹配 (1)。您从查询中获得的结果数是 m×n,但您从不使用 ?s 的值。看起来您使用 DISTINCT 去除了一些重复值,但您并没有看到 为什么 一开始就会得到重复值。您应该简单地删除无用的行 (1),并进行查询:

    SELECT DISTINCT ?position    
    WHERE {     
        ?position skos:prefLabel|skos:altLabel ?label
        FILTER (lcase(?label)="acuponcteur"@fr ) 
    }
    

    如果此时您甚至不再需要 DISTINCT,我不会感到惊讶。

    【讨论】:

    • 我很惭愧我的问题实际上是这个 ?s 错误... ?s 应该是 ?position 因为我只想选择属于 rdf:type esco:Occupation 的 ?position uri。感谢 UNION 的简化!至于数据集读取和模型创建,我实际上把它放在另一个类中,这样它就不必每次都经过这个,但我简化了问题的代码。
    猜你喜欢
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    • 2023-03-20
    • 2013-06-09
    相关资源
    最近更新 更多