1

我想过滤一个模型,获取所有具有特定谓词和 C 类型主题的三元组。下面的代码不返回任何结果,有没有人知道如何实现它?

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

1 回答 1

1

问题是您将第二个应用于第filter一个的结果 - 但第一个过滤器的结果包含具有您过滤的属性的三元组 - 所以第二个过滤器永远不会返回空结果(因为没有三元组在中间结果中会有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 回答