Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find lists containing ALL values in a set?

Tags:

rdf

sparql

How can I find lists that contain each of a set of items in SPARQL? Let's say I have this data:

<http://foo.org/test> <http://foo.org/name> ( "new" "fangled" "thing" )  . 
<http://foo.org/test2> <http://foo.org/name> ( "new" "york" "city" )  . 

How can I find the items whose lists contain both "new" and "york"? The following SPARQL doesn't work, since filter works on each binding of ?t, not the set of all of them.

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ?s ?p WHERE {       
    ?s <http://foo.org/name>/rdf:rest*/rdf:first ?t 
    FILTER( ?t = "new" && ?t = "york")   
}
like image 537
Aries On The Cusp Avatar asked Jan 27 '16 01:01

Aries On The Cusp


1 Answers

Finding lists with multiple required values

If you're looking for lists that contain all of a number of values, you'll need to use a more complicated query. This query finds all the ?s values that have a ?list value, and then filters out those where there is not a word that is not in the list. The list of words is specified using a values block.

prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?s {
  ?s <http://foo.org/name> ?list .
  filter not exists {                   #-- It's not the case
     values ?word { "new" "york" }      #-- that any of the words
     filter not exists {                #-- are not
       ?list rdf:rest*/rdf:first ?word  #-- in the list.
     }
  }
}
--------------------------
| s                      |
==========================
| <http://foo.org/test2> |
--------------------------

Find alternative strings in a list

On the other hand, if you're just trying to search for one of a number of options, you're using the right property path, but you've got the wrong filter expression. You want strings equals to "new" or "york". No string is equal to both "new" and "york". You just need to do filter(?t = "new" || ?t = "york") or better yet use in: filter(?t in ("new", "york")). Here's a full example with results:

prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?s ?t {
  ?s <http://foo.org/name>/rdf:rest*/rdf:first ?t .
  filter(?t in ("new","york"))
}
-----------------------------------
| s                      | t      |
===================================
| <http://foo.org/test2> | "new"  |
| <http://foo.org/test2> | "york" |
| <http://foo.org/test>  | "new"  |
-----------------------------------
like image 185
Joshua Taylor Avatar answered Sep 19 '22 11:09

Joshua Taylor