2017-02-12 58 views
0

我正在用Jena 3.1.0试用SPARQL。我必须从资源列表中获得每个资源20公里范围内的资源。SPARQL用于查找距离资源20km以内的东西

我做了这个SPARQL查询:click me。它适用于DBpedia端点,但它在Java中不起作用。

这里是我的代码。

public class SKPQSearch { 

    static Model model = getTestModel(); 
    public static char quotes = '"'; 
    public static boolean USING_GRAPH = false; 

    public static void main(String[] args) { 

     List<Resource> interestObject = new ArrayList<Resource>(); 
     List<Resource> features = new ArrayList<Resource>(); 

     interestObject = searchObjectofInterest("Hotel"); 
     features = findFeatures(interestObject); 

     Iterator<Resource> it = features.iterator(); 

     System.out.println("Features.....\n\n"); 

     while (it.hasNext()) { 
      System.out.println(it.next().getURI()); 
     }     } 

    public static Model getTestModel() { 

     Model model = ModelFactory.createDefaultModel(); 
     return model; 

    } 

    public static List<Resource> findFeatures(List<Resource> interestSet) { 

     List<Resource> featureSet = new ArrayList<>(); 

     String serviceURI = "http://dbpedia.org/sparql"; 

     for (int a = 0; a < interestSet.size(); a++) { 

      String queryString = "" + Sparql.addService(USING_GRAPH, serviceURI) 
        + "SELECT DISTINCT ?resource WHERE { <" + interestSet.get(a).getURI() 
        + "> geo:geometry ?sourcegeo." + " ?resource geo:geometry ?location ;" + "rdfs:label ?label ." 
        + "FILTER(bif:st_intersects(?location, ?sourcegeo, 20))." + "FILTER(lang(?label) =" + quotes 
        + "en" + quotes + ")}" + Sparql.addServiceClosing(USING_GRAPH); 

      Query query = QueryFactory.create(Sparql.addPrefix().concat(queryString)); 

      try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) { 

       Map<String, Map<String, List<String>>> serviceParams = new HashMap<String, Map<String, List<String>>>(); 
       Map<String, List<String>> params = new HashMap<String, List<String>>(); 
       List<String> values = new ArrayList<String>(); 
       values.add("20000"); 
       params.put("timeout", values); 
       serviceParams.put(serviceURI, params); 
       qexec.getContext().set(ARQ.serviceParams, serviceParams); 
       try { 
        ResultSet rs = qexec.execSelect(); 
        System.out.println(rs.hasNext()); 
        for (; rs.hasNext();) { 
         QuerySolution rb = rs.nextSolution(); 

         RDFNode x = rb.get("resource"); 
         if (x.isResource()) { 
          featureSet.add((Resource) x); 
         } 
        } 
       } finally { 
        qexec.close(); 
       } 
      } 
     } 
     return featureSet; 
    } 

    public static List<Resource> searchObjectofInterest(String object) { 

     List<Resource> resources = new ArrayList<Resource>(); 

     String serviceURI = "http://dbpedia.org/sparql"; 

     String queryString = "" + Sparql.addService(USING_GRAPH, serviceURI) + "SELECT distinct ?hotel " + "WHERE { " 
       + " ?hotel a <http://dbpedia.org/ontology/" + object + ">. }" + " LIMIT 1" 
       + Sparql.addServiceClosing(USING_GRAPH); 

     Query query = QueryFactory.create(Sparql.addPrefix().concat(queryString)); 

     try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) { 

      Map<String, Map<String, List<String>>> serviceParams = new HashMap<String, Map<String, List<String>>>(); 
      Map<String, List<String>> params = new HashMap<String, List<String>>(); 
      List<String> values = new ArrayList<String>(); 
      values.add("20000"); 
      params.put("timeout", values); 
      serviceParams.put(serviceURI, params); 
      qexec.getContext().set(ARQ.serviceParams, serviceParams); 
      try { 
       ResultSet rs = qexec.execSelect(); 

       for (; rs.hasNext();) { 
        QuerySolution rb = rs.nextSolution(); 

        RDFNode x = rb.get("hotel"); 
        if (x.isResource()) { 
         resources.add((Resource) x); 
        } 
       } 
      } finally { 
       qexec.close(); 
      } 
      return resources; 
     }  } } 

Sparql.addService方法

public static String addService(boolean usingGraph, String serviceURI) { 
    if (!usingGraph) { 
     return "SELECT DISTINCT * WHERE { SERVICE <" + serviceURI + ">{"; 
    } else { 
     return " "; 
    } 
} 

查询例如:click me

PS:我使用的前缀:PREFIX geo: <http://www.opengis.net/ont/geosparql#>

+0

目前尚不清楚Sparql.addService是做什么的,但我猜想它会以某种方式生成联合查询?否则,您将针对空模型运行SPARQL查询。出于调试的目的,如果您提供完整的最终查询以查看真正执行的内容,则更容易。 – AKSW

+2

Jena不支持GeoSPARQL:它提供了基本的空间搜索功能。 http://jena.apache.org/documentation/query/spatial-query.html'bif:st_intersects'不是GeoSPARQL,也不是耶拿 - 它是Virtuoso特有的。 – AndyS

+0

@AndyS我认为他在DBpedia端点上运行一个联邦查询,因此这里没关系。至少这就是我在看代码时所假设的,有一些神奇的行'Sparql.addService(USING_GRAPH,serviceURI)'。否则,整个查询将在一个空的Jena模型上运行。 – AKSW

回答

0

我已经找到了解决我的问题。

由于某种原因,我不能在bif:st_intersects(?location, ?sourcegeo, 20)中使用bif前缀。所以我把完整的URI FILTER (<http://www.openlinksw.com/schema/sparql/extensions#bif:st_intersects(?location,?sourcegeo,20)>)

编辑:继@TallTed建议,我已经更新了我的Sparql.addPrefix()方法,并把它PREFIX bif: <bif:>。这样我就不必在我的SPARQL查询中使用完整的URI。

public static String addPrefix() { 
     String prefix = "" + "PREFIX owl: <http://www.w3.org/2002/07/owl#>"     
       + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> " 
       + "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> " 
       + "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " 
       + "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " 
       + "PREFIX dc: <http://purl.org/dc/elements/1.1/> " 
       + "PREFIX bif: <bif:>" 
       + "PREFIX : <http://dbpedia.org/resource/> " 
       + "PREFIX dbpedia2: <http://dbpedia.org/property/> " 
       + "PREFIX dbpedia: <http://dbpedia.org/> " 
       + "PREFIX skos: <http://www.w3.org/2004/02/skos/core#> " 
       + "PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>" 
       + "PREFIX e: <http://learningsparql.com/ns/expenses#> " 
       + "PREFIX d: <http://learningsparql.com/ns/data#> "; 
     return prefix; 
+0

您可能会发现使用'+“PREFIX bif:”'为您带来CURIe的成功。 – TallTed

+0

感谢@TallTed这个创意。有用!但是我不明白它是如何在没有<

+0

'bif:'是一个内置的Virtuoso前缀(和SPARQL中的URI方案),代表'built-in function'。在提交给后端之前,您只需要用于预解析SPARQL的工具的'PREFIX'语句。这些工具通常不检查扩展CURIe的有效性;他们只是检查是否有扩张。 – TallTed