Select multiple values as object in SPARQL pattern

0xFF picture 0xFF · Jul 11, 2013 · Viewed 8.4k times · Source

In SPARQL we can do something like this

select * where {
    ?s   (_:prop1 | _:prop2)  "some_val" .
    ...
    #use ?s in other patterns
    ?s    ?o    ?p .
}

Is it possible to do the same for the object part of the pattern? And what are some workarounds of this in case it is not possible?

For example:

select * where {
    ?s   _:prop ("v1" | "v2") .
    ...
    #use ?s in other patterns
    ?s    ?o    ?p .
}

Answer

RobV picture RobV · Jul 11, 2013

There are a few ways to do this. The simplest and pure SPARQL 1.0 method is to use UNION e.g.

SELECT * WHERE
{
  { ?s _:prop "v1" } UNION { ?s _:prop "v2" }

  # Use ?s in other patterns
}

This is probably the simplest method but if you need multiple constraints on ?s this can quickly get unwieldy.

Second method is to use the IN function in a FILTER clause, this requires a SPARQL 1.1 implementation e.g.

SELECT * WHERE
{
  ?s _:prop ?value .
  FILTER(?value IN ("v1", "v2"))

  # Use ?s in other patterns
}

Problem here is that using IN can perform very poorly if you have many alternatives or a lot of data that may be matched by ?s _:prop ?value

Aside - Many optimisers will actually expand this second method into the first method under the hood.

Third method is to use the VALUES clause which again requires a SPARQL 1.1 implementation:

SELECT * WHERE
{
  VALUES (?value) { ( "v1" ) ( "v2 " ) }
  ?s _:prop ?value .

  # Use ?s in other patterns
}

This is likely the best option since it scales to many alternatives better (depending on your SPARQL implementation) and is maybe the nicest to read and write.