モデルをフィルタリングし、特定の述語とタイプ C の主語を持つすべてのトリプルを取得したいと思います。以下のコードは結果を返しません。実装方法を知っている人はいますか?
return triples.filter(null, new URIImpl(property.getFullIRI()), null).filter
(null, RDF.TYPE,new URIImpl(C.getFullIRI()));
問題はfilter
、最初の結果に 2 番目のフィルターを適用していることです。ただし、最初のフィルターの結果には、フィルター処理したプロパティを持つトリプルのみが含まれます。そのため、2 番目のフィルターは空の結果以外を返すことはできません (トリプルがないため)。中間結果にはrdf:type
述語があります)。
このように「ノンシーケンシャル」な二次制約を表現しているため、フィルタリングだけでは解決できません。作業を進めながら、新しい を構築Model
してデータを入力する必要があります。これらの行に沿ったもの:
// always use a ValueFactory, avoid instantiating URIImpl directly.
ValueFactory vf = ValueFactoryImpl().getInstance();
URI c = vf.createURI(C.getFullIRI());
URI prop = vf.createURI(property.getFullIRI())
// create a new Model for the resulting triple collection
Model result = new LinkedHashModel();
// filter on the supplied property
Model propMatches = triples.filter(null, prop, null);
for(Resource subject: propMatches.subjects()) {
// check if the selected subject is of the supplied type
if (triples.contains(subject, RDF.TYPE, c)) {
// add the type triple to the result
result.add(subject, RDF.TYPE, c);
// add the property triple(s) to the result
result.addAll(propMatches.filter(subject, null, null));
}
}
return result;
上記は Sesame 2 で機能します。Sesame 4 (Java 8 とその Stream API をサポート) を使用している場合は、次のように、より簡単に行うことができます。
return triples.stream().filter(st ->
{
if (prop.equals(st.getPredicate()) {
// add this triple if its subject has the correct type
return triples.contains(st.getSubject(), RDF.TYPE, c));
} else if (RDF.TYPE.equals(st.getPredicate())
&& c.equals(st.getObject()) {
// add this triple if its subject has the correct prop
return triples.contains(st.getSubject(), prop, null);
}
return false;
}).collect(Collectors.toCollection(LinkedHashModel::new));