How do I get intersection-like behavior with SPARQL 1.1 VALUES?

Using 1.1 SPARQL values , the following query returns all predicates using the Einstein or Knuth the object (together with their labels).

PREFIX dbp: <http://dbpedia.org/resource/>

SELECT DISTINCT ?sub ?outpred ?label
{
  VALUES ?sub { dbp:Albert_Einstein dbp:Donald_Knuth }
  ?sub ?outpred [] .
  ?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}

      

SPARQL Results

Is it possible to use this value function to detect intersection rather than union of predicates? Or am I misunderstanding what's for the values ?

EDIT: Clarification

For a simplified example, let's say there are the following triplets:

<Einstein>  <influenced>    <John>
<Einstein>  <influenced>    <Knuth>
<Einstein>  <born>          <Mars>
<Einstein>  <died>          <Los Angeles>
<Knuth>     <influenced>    <Kirby>
<Knuth>     <born>          <Mars>
<Knuth>     <wrote>         <TAOCP>
<Knuth>     <drove>         <Truck>

      

The "union" I get is all unique predicates tied to any subject (the line is split for clarity):

|  ?sub    |  ?pred     |
-------------------------
<Einstein>  <influenced>
<Knuth>     <influenced>

<Einstein>  <born>
<Knuth>     <born>

<Einstein>  <died>

<Knuth>     <wrote>

<Knuth>     <drove>

      

The "intersection" I got is all the unique predicates common to both items:

|  ?sub    |  ?pred     |
-------------------------
<Einstein>  <influenced>
<Knuth>     <influenced>

<Einstein>  <born>
<Knuth>     <born>

      

+3


source to share


1 answer


Solutions

You can use a query like this. The trick is to group using a predicate and only accept those predicates for which there are exactly two subjects (Einstein and Knuth).

select distinct ?outpred ?label
{
  values ?sub { dbp:Albert_Einstein dbp:Donald_Knuth }
  ?sub ?outpred [] .
  ?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}
group by ?outpred ?label
having count(distinct ?sub) = 2

      

Of course, this requires getting all the data you need to combine, and then compressing it. I don't expect this to be a big problem, but if it is (for example, if you are trying to traverse a lot of items), you can also just list the items separately:

select distinct ?outpred ?label
{
  dbp:Albert_Einstein ?outpred [].
  dbp:Donald_Knuth ?outpred [].
  ?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}

      

Discussion

Is it possible to use this VALUES function to open intersection rather than union of predicates? Or am I not understanding what VALUES are meant for?

The values โ€‹โ€‹are just another set of bindings that connect to other bindings, so it cannot do the intersection for you the way you would like it to. However, doing the "intersection" of the sort you are looking for here is not too difficult:

select distinct ?outpred ?label
{
  dbp:Albert_Einstein ?outpred [] .
  dbp:Donald_Knuth ?outpred [] .
  ?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}

      

Now, having said that there can be a lot of ternary patterns to write, so you might need some sort of query where the only thing you need to change is a list of values. You can specify values โ€‹โ€‹and then group by property and label (i.e. Variables with no values) and just take those solutions for which count(distinct ?sub)

is the number of values โ€‹โ€‹you specify. For example:.

select distinct ?outpred ?label
{
  values ?sub { dbp:Albert_Einstein dbp:Donald_Knuth }
  ?sub ?outpred [] .
  ?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}
group by ?outpre ?label
having count(distinct ?sub) = 2

      

Thus, to get count(distinct ?sub)

equal to 2, you must have matched ?sub ?outpred []

for ?sub = Einstein

and ?sub = Knuth

.

Approach check

We can use the DBpedia endpoint to work with them. First, a simplified query:



select distinct ?s ?p where {
  values ?s { dbpedia:Albert_Einstein dbpedia:Donald_Knuth }
  ?s ?p []
}

      

SPARQL Results

s                                             p
http://dbpedia.org/resource/Albert_Einstein   http://www.w3.org/1999/02/22-rdf-syntax-ns#type
http://dbpedia.org/resource/Donald_Knuth      http://www.w3.org/1999/02/22-rdf-syntax-ns#type
http://dbpedia.org/resource/Albert_Einstein   http://www.w3.org/2002/07/owl#sameAs
http://dbpedia.org/resource/Donald_Knuth      http://www.w3.org/2002/07/owl#sameAs
โ‹ฎ                                            โ‹ฎ

      

Now there is no point in asking for an intersection while we are still choosing ? s , because Einstein & ne; Knut, so there never was a crossroads. But can we take the intersection on ? P . Here's a query that gets all properties for which both values โ€‹โ€‹are valid:

select distinct ?p where {
  dbpedia:Albert_Einstein ?p [] .
  dbpedia:Donald_Knuth ?p []
}

      

SPARQL Results

A similar query calculates the results for us:

select (count(distinct ?p) as ?np) where {
  dbpedia:Albert_Einstein ?p [] .
  dbpedia:Donald_Knuth ?p [] .
}

      

There are 45 properties that both have.

Request for -

select distinct ?p where {
  values ?s { dbpedia:Albert_Einstein dbpedia:Donald_Knuth }
  ?s ?p []
}
group by ?p
having count(?s) = 2

      

Now let's make sure the other approach gets the same results:

select (count(*) as ?np) where {
  select distinct ?p where {
    values ?s { dbpedia:Albert_Einstein dbpedia:Donald_Knuth }
    ?s ?p []
  }
  group by ?p
  having count(distinct ?s) >= 2
}

      

This also returns 45, so we can see that we are getting the same results.

+4


source







All Articles