Вам нужно немного отступить и более четко подумать о том, что вы пытаетесь сделать. Ваш sparql-запрос, после того как он будет исправлен (см. ниже), отлично справится с созданием итератора по набору результатов, который предоставит вам свойства каждого из документов, которые вы ищете. В частности, вы получаете один набор привязок для каждого из s2
, p2
и o2
для каждого значения в наборе результатов. Это то, что вы просите, когда указываете select ?s2 ?p2 ?o2
. И обычно это то, что вы хотите: обычно мы выбираем некоторые значения из тройного хранилища, чтобы каким-то образом их обработать (например, отобразить их в списке в пользовательском интерфейсе), и для этого нам как раз нужен итератор по результатам. Вы можете сделать так, чтобы запрос возвращал вам модель, а не набор результатов, благодаря SPARQL построить запрос или SPARQL описать а>. Однако затем вам нужно перебрать ресурсы в модели, поэтому вы не намного продвинетесь вперед (за исключением того, что ваша модель меньше и находится в памяти).
Ваш запрос, кстати, можно улучшить. Переменные p1
и o1
заставляют механизм запросов выполнять бесполезную работу, поскольку вы никогда их не используете, и нет необходимости в объединении. Исправлено, ваш запрос должен быть:
PREFIX base:<http://example#>
select ?s2 ?p2 ?o2
where {
?doc base:fullName <file:/c:/1.txt> .
?s2 base:documentID ?doc ;
?p2 ?o2 .
}
Для выполнения любого запроса, выбора, описания или построения из Java см. документацию Jena. .
Вы можете эффективно достичь тех же результатов, что и ваш запрос, используя API модели. Например, (не проверено):
Model m = ..... ; // your model here
String baseNS = "http://example#";
Resource fileName = m.createResource( "file:/c:/1.txt" );
// create RDF property objects for the properties we need. This can be done in
// a vocab class, or automated with schemagen
Property fullName = m.createProperty( baseNS + "fullName" );
Property documentID = m.createProperty( baseNS + "documentID" );
// find the ?doc with the given fullName
for (ResIterator i = m.listSubjectsWithProperty( fullName, fileName ); i.hasNext(); ) {
Resource doc = i.next();
// find all of the ?s2 whose documentID is ?doc
for (StmtIterator j = m.listStatements( null, documentID, doc ); j.hasNext(); ) {
Resource s2 = j.next().getSubject();
// list the properties of ?s2
for (StmtIterator k = s2.listProperties(); k.hasNext(); ) {
Statement stmt = k.next();
Property p2 = stmt.getPredicate();
RDFNode o2 = stmt.getObject();
// do something with s2 p2 o2 ...
}
}
}
Обратите внимание, что ваш дизайн схемы делает это более сложным, чем это необходимо. Если, например, ресурс полного имени документа имеет свойство base:isFullNameOf
, то вы можете просто выполнить поиск, чтобы получить свойство doc
. Точно так же непонятно, зачем нужно различать doc
и s2
: почему бы просто не привязать свойства документа к ресурсу doc
?
Наконец: нет, открытие соединения с базой данных не загружает всю БД в память. Однако, в частности, TDB широко использует кэширование областей графа, чтобы сделать запросы более эффективными.
person
Ian Dickinson
schedule
27.07.2012