2

In RDF, I can have an entity that is bound by a single property to multiple literal values. Those values can also be typed to add clarity.

:dumpTruck :weight "heavy"^^xsd:string .
:dumpTruck :weight "36000"^^xsd:integer .

In SPARQL, I can query for just they type I want

SELECT  ?w
WHERE
  { :dumpTruck  :weight  ?w
    FILTER ( datatype(?w) = xsd:integer )
  }

Is there something like getStatement in RDF4J that can be constrained by datatype like that?

Mark Miller
  • 3,011
  • 1
  • 14
  • 34
  • No, there isn't as it is for remote repositories this would need too much effort in providing query templates. - even not for the in-memory model. But you could write your own utility class that provides those convenience methods. – UninformedUser Jul 25 '17 at 18:43
  • like running `getStatement`, then string-splitting the statement objects on `^^xsd:`, and then `grep`ing for my desired xsd type in chunk 2 of the split array? – Mark Miller Jul 25 '17 at 19:01
  • 1
    Sometimes, just because you *can* do something, doesn't mean you *should* do it. Better overall results would come from `{ :dumpTruck :weightClass "heavy"^^xsd:string ; :weightKilograms "36000"^^xsd:integer . }`. `:weightClass` even becomes inferrable from `:weightKilograms` values. – TallTed Jul 25 '17 at 19:11
  • @TallTed... right, that was exactly what I was trying to avoid! Sorry, should have added that to the question. If possible, I'd like to stick to realist/BFO principles. I may just go with scalar values specifications http://www.ontobee.org/ontology/OBI?iri=http://purl.obolibrary.org/obo/OBI_0001931 . – Mark Miller Jul 25 '17 at 19:16

1 Answers1

2

There's no a priori constraint possible, but you can post-process your result to filter on the datatype. For example you could use something along these lines (untested but you get the drift hopefully):

QueryResults.stream(conn.getStatements(dumptruck, weight, null))
            .filter(s -> ((Literal)s.getObject()).getDatatype().equals(XMLSchema.INTEGER))
            .collect(Collectors.toList());

Or alternatively, stick in a Model first and then filter:

Model m = QueryResults.asModel(conn.getStatements(dumptruck, weight, null));
List intValues = Models.objectLiterals(m).stream().filter(l -> l.getDatatype().equals(XMLSchema.INTEGER)).collect(Collectors.toList()); 

I'm sure there's a couple of other/handier shortcuts available that I haven't thought of. The RDF4J docs have tutorials and examples to spare, however.

Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73