1

モデルをフィルタリングし、特定の述語とタイプ C の主語を持つすべてのトリプルを取得したいと思います。以下のコードは結果を返しません。実装方法を知っている人はいますか?

return triples.filter(null,  new URIImpl(property.getFullIRI()), null).filter
(null, RDF.TYPE,new URIImpl(C.getFullIRI()));
4

1 に答える 1

1

問題は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));  
于 2016-01-15T23:06:10.370 に答える