#java #oracle #rdf #sparql #jena
#java #Oracle #rdf #sparql #jena
Вопрос:
Я пытаюсь изучить основы работы с тройками Jena и RDF. Также работаю с базой данных Oracle, поэтому, следуя их руководству, у меня есть несколько примеров запущенных программ, таких как Example7-18 SPARQL OPTIONAL Query. Пример работает нормально, как написано. Это позволяет сопоставлять запросы, такие как
where {?s <u:parentOf> ?o}
where {<u:John> <u:parentOf> <u:Mary>}
Что я хотел бы сделать, так это указать возраст Джона, Мэри и Джилл каждому, чтобы я мог запрашивать и фильтровать по возрасту, как описано в SPARQL На примере: Шпаргалка, страница 10:
A . B . FILTER ( …expr… )
where {?s <u:parentOf> ?o . ?o <u:isAge> ?a . filter ( ?a < 20 ) }
С текущим кодом для троек я могу добавлять только строки / узлы URI, и хотя я мог бы создать тройку, такую как <u:John> <u:isAge> <u:35>
, я не могу фильтровать и сравнивать, например, с оператором < для этого возраста, поэтому это не очень полезно.
Я уже некоторое время осматриваюсь и подозреваю, что сделать это очень просто, но образцы кода было трудно найти.
Комментарии:
1. Обратите внимание, что текст, который нравится
<u:John> <u:isAge> <u:35>
, обрабатывается в редакторе как разметка, поэтому вам нужно окружить его обратными метками`
, иначе его никто не увидит. Я исправил это в этом случае.
Ответ №1:
Обратите внимание, что вам нужен объект типа "35"^^xsd:int
or "35^^xsd:integer
, который является литералами, а не <u:35>
который является (возможно, искаженным) URI. Пример, на мой взгляд, делает что-то несколько необычным образом, и, согласно документации, он использует некоторые устаревшие методы. Во всяком случае, вы можете видеть, что он создает узлы URI с помощью методов из класса Node (заводского класса):
Node.createURI("u:John")
Node.createURI("u:parentOf")
Node.createURI("u:Mary")
В классе Node существует пять методов createLiteral, и вы можете использовать createLiteral(String lex, RDFDatatype dtype) для создания литерала с типом данных. Однако этот метод устарел, и вместо него вам действительно следует использовать один из методов из NodeFactory.
Все это говорит о том, что я не знаю, есть ли какая-либо причина, по которой в примере используется интерфейс graph для создания троек, а не интерфейс модели. У вас уже есть модель из:
ModelOracleSem model = ModelOracleSem.createOracleSemModel(oracle, szModelName);
и эту задачу намного проще выполнить, если вы используете интерфейс модели, где у вас есть такие методы, как createTypedLiteral, чтобы вы могли просто вызвать createTypedLiteral(30)
и получить обратно подходящий литерал. Вот пример:
import java.math.BigInteger;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
public class CreateAndQueryExample {
/**
* @param args
*/
public static void main(String[] args) {
// You should be able to replace this with the Oracle model
// producing code.
Model model = ModelFactory.createDefaultModel();
Resource john = model.createResource( "urn:ex:John" );
Resource mary = model.createResource( "urn:ex:Mary" );
Property age = model.createProperty( "urn:ex:age" );
// Using Model.add method
model.add( john, age, model.createTypedLiteral( new BigInteger( "25" ))); // "25"^^xsd:integer
// model.add( john, age, model.createTypedLiteral( 25 )); // "25"^^xsd:int
// model.add( john, age, model.createTypedLiteral( 25l )); // "25"^^xsd:long
// Using the Resource.addProperty method
mary.addProperty( age, model.createTypedLiteral( new BigInteger( "35" )));
Query query = QueryFactory.create( "select * where { ?s <urn:ex:age> ?age . filter ( ?age < 30 ) }" );
QueryExecution exec = QueryExecutionFactory.create( query, model );
ResultSetFormatter.out( exec.execSelect() );
}
}
-----------------------
| s | age |
=======================
| <urn:ex:John> | 25 |
-----------------------
Комментарии:
1. Спасибо, это полезно, но вы не указали отношения ‘<parentOf>’ между ресурсами. Не могли бы вы добавить их также с помощью model.add, как если бы они были литералами? Какая разница, добавляю ли я свои отношения как литералы или как тройки?
2. @user985366 Я их не пропустил. В вашем вопросе был задан вопрос о добавлении возраста (целочисленных литералов) в тройки Jena RDF и выполнении запросов к ним с помощью SPARQL, и этот ответ показывает, как сделать обе эти вещи. У вас уже есть способ добавления узлов создания URI, и если вы хотите сделать это с помощью интерфейса модели и связанных интерфейсов, в ответе есть ссылки на эти интерфейсы.
3. Если вы собираетесь написать подобный шаблон
?s :parentOf ?o . ?o :hasAge ?a
, то parentOf должен быть отношением между ресурсами (т.Е. Пустыми узлами и узлами URI, но не литералами). Литералы не могут быть предметом троек, поэтому, если вы использовали литерал в parentOf , например,:John :parentOf "Mary"
, вам не повезло во второй тройке, потому что вы не можете сказать"Mary" :hasAge 25
.