Sparql заявката работи вечно

Затруднявам се с изпълнението на SPARQL заявка в Jena, с резултатно поведение, което не разбирам...

Опитвам се да направя заявка в онтологията на 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();
      }

}

Какво правя грешно тук? Някаква идея?

Благодаря!


person CecileR    schedule 14.08.2014    source източник


Отговори (1)


Като първа точка, която може или не може да има голяма разлика, можете да използвате път на свойство за опростяване

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

Какъв е смисълът от ?s в тази заявка? Има определен брой n двойки ?позиция/?етикет, които съвпадат (2), и известен брой m стойности на ?s, които съвпадат (1). Броят резултати, които получавате от заявката, е mn, но никога не използвате стойността на ?s. Изглежда, че сте използвали DISTINCT, за да се отървете от някои повтарящи се стойности, но не сте проверили защо получавате повтарящи се стойности на първо място. Трябва просто да премахнете безполезния ред (1) и да имате заявката:

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

Няма да се изненадам, ако в този момент дори вече нямате нужда от DISTINCT.

person Joshua Taylor    schedule 14.08.2014
comment
Толкова се срамувам, че проблемът ми всъщност беше тази ?s грешка... ?s трябва да бъде ?position, тъй като исках да избера само ?position uri, които са от rdf:type esco:Occupation. Благодаря за опростяването за UNION! А що се отнася до четенето на набор от данни и създаването на модел, всъщност го поставих в друг клас, така че да не се налага да минава през това всеки път, но опростих кода за въпроса. - person CecileR; 14.08.2014