You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于联邦查询构建RDF图:SPARQL跨Wikidata与DBpedia求助

Federated SPARQL Query for Wikidata/DBpedia & RDF Graph Building in Apache Jena

Hey there! Let's walk through refining your query into a proper SPARQL 1.1 federated query, then cover how to test it in Apache Jena and build an RDF graph from the results.

Step 1: Fix the Federated Query

Your original query uses UNION but doesn't explicitly target the respective Wikidata/DBpedia endpoints—this isn't a true federated query. Instead, use SERVICE clauses to specify which endpoint each subquery should run against. Here's an improved version that links results across both datasets and adds human-readable labels:

PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbr: <http://dbpedia.org/resource/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>

SELECT DISTINCT ?film ?filmLabel ?wikidataUri ?dbpediaUri WHERE {
  # Query Wikidata for Leonardo's films
  SERVICE <http://query.wikidata.org/sparql> {
    ?wikidataUri wdt:P161 wd:Q38111 ;  # Q38111 = Leonardo DiCaprio (Wikidata)
                rdfs:label ?filmLabel .
    FILTER(LANG(?filmLabel) = "en")
  }

  # Optional: Link to DBpedia if the film has a matching entry
  OPTIONAL {
    SERVICE <http://dbpedia.org/sparql> {
      ?dbpediaUri dbo:starring dbr:Leonardo_DiCaprio ;
                  rdfs:label ?filmLabel ;
                  owl:sameAs ?wikidataUri .  # Link Wikidata/DBpedia entities
      FILTER(LANG(?filmLabel) = "en")
    }
  }

  # Use Wikidata URI as primary film identifier (fallback to DBpedia if needed)
  BIND(COALESCE(?wikidataUri, ?dbpediaUri) AS ?film)
}

Key improvements:

  • Explicit SERVICE clauses target each dataset's public SPARQL endpoint
  • OPTIONAL handles cases where a film might not exist in both datasets
  • owl:sameAs links matching entities across Wikidata and DBpedia
  • COALESCE provides a consistent ?film identifier
  • DISTINCT removes duplicate results from overlapping entries
  • English labels make results easier to interpret

Step 2: Test the Query in Apache Jena

You can test this query using either Apache Jena Fuseki (the web-based triplestore) or the Jena Java API.

Option A: Using Jena Fuseki

  1. Download and start the Fuseki server (ensure you have the latest version)
  2. Navigate to the Fuseki web interface (default: http://localhost:3030)
  3. Go to the "Query" tab, paste the federated query, and click "Run Query"
    • Note: Fuseki allows federated queries by default, but if you run into issues, add fuseki:allowFederatedQueries true to your Fuseki configuration file.

Option B: Using the Jena Java API

Here's a code snippet to execute the query and build an RDF model from the results:

import org.apache.jena.query.*;
import org.apache.jena.rdf.model.*;
import org.apache.jena.vocabulary.RDFS;
import org.apache.jena.vocabulary.OWL;
import java.io.FileWriter;

public class LeoFilmGraphBuilder {
    public static void main(String[] args) {
        // Define the federated SPARQL query
        String sparql = """
            PREFIX wd: <http://www.wikidata.org/entity/>
            PREFIX wdt: <http://www.wikidata.org/prop/direct/>
            PREFIX dbo: <http://dbpedia.org/ontology/>
            PREFIX dbr: <http://dbpedia.org/resource/>
            PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
            PREFIX owl: <http://www.w3.org/2002/07/owl#>

            SELECT DISTINCT ?film ?filmLabel ?wikidataUri ?dbpediaUri WHERE {
              SERVICE <http://query.wikidata.org/sparql> {
                ?wikidataUri wdt:P161 wd:Q38111 ;
                            rdfs:label ?filmLabel .
                FILTER(LANG(?filmLabel) = "en")
              }

              OPTIONAL {
                SERVICE <http://dbpedia.org/sparql> {
                  ?dbpediaUri dbo:starring dbr:Leonardo_DiCaprio ;
                              rdfs:label ?filmLabel ;
                              owl:sameAs ?wikidataUri .
                  FILTER(LANG(?filmLabel) = "en")
                }
              }

              BIND(COALESCE(?wikidataUri, ?dbpediaUri) AS ?film)
            }
            """;

        // Execute the federated query
        try (QueryExecution qe = QueryExecutionFactory.sparqlService("http://query.wikidata.org/sparql", sparql)) {
            ResultSet results = qe.execSelect();

            // Create an empty RDF model to store our film graph
            Model filmGraph = ModelFactory.createDefaultModel();
            Property starredIn = filmGraph.createProperty("http://example.org/ontology/starredIn");
            Resource leonardo = filmGraph.createResource("http://www.wikidata.org/entity/Q38111");
            leonardo.addProperty(RDFS.label, "Leonardo DiCaprio", "en");

            // Populate the model with query results
            while (results.hasNext()) {
                QuerySolution sol = results.nextSolution();
                Resource film = sol.getResource("film");
                film.addProperty(RDFS.label, sol.getLiteral("filmLabel"));

                // Link Leonardo to the film
                filmGraph.add(leonardo, starredIn, film);

                // Add sameAs links if both URIs exist
                if (sol.contains("wikidataUri") && sol.contains("dbpediaUri")) {
                    film.addProperty(OWL.sameAs, sol.getResource("dbpediaUri"));
                }
            }

            // Write the RDF graph to console in Turtle format (easy to read)
            System.out.println("Generated RDF Graph (Turtle):");
            filmGraph.write(System.out, "TURTLE");

            // Optional: Save the graph to a file for later use
            filmGraph.write(new FileWriter("leonardo-films.ttl"), "TURTLE");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Step 3: Tips for Working with the RDF Graph

  • Persist the Graph: Use Jena's Model.write() method to save the graph to a file in formats like Turtle, RDF/XML, or JSON-LD.
  • Query the Local Graph: Load the saved model into Fuseki or use the Jena API to run local SPARQL queries on your custom film graph.
  • Handle Rate Limits: Public Wikidata/DBpedia endpoints have rate limits—avoid running large, frequent queries to avoid being blocked.
  • Expand the Graph: Add more properties (like release dates, genres) to your query to enrich the RDF model with extra metadata.

内容的提问来源于stack exchange,提问作者Aziz Mumtaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:00:16