2

有没有办法在sparql中确保检索期间的顺序?

假设我想将List<Literals>(重要的订单)存储为对象

{:subj :pred 'o1'. :subj :pred 'o2'. :subj :pred 'o3'}

如何插入上述数据,以便在执行select ?s ?p ?o where {?s ?p ?o}订单时不会更改?

sparql 在检索时是否始终保留插入数据顺序?

在上面的例子中,我以文字为例。有没有办法保留 IRI 的顺序?

我在 sparql 上看过文档RDF.Seq,但我并不完全了解如何使用它。请提供一些简单的插入和选择查询以确保订单或共享任何相关资源。

4

2 回答 2

3

如果需要保持顺序,可以将列表表示为 RDF 集合。如果您有一个字符串列表,例如:

 List<String> objects = Arrays.asList("o1", "o2", "o3");

将其表示为 RDF 集合看起来像这样(在 Turtle 语法中):

_:node a rdf:List;
       rdf:first "o1" ;
       rdf:rest [ 
          rdf:first "o2";
          rdf:rest [
             rdf:first "o3";
             rdf:rest rdf:nil .
          ]
       ].          

这可能看起来很麻烦,但是 RDF4J 库提供了一些RDF 集合实用程序,以便从代码中更轻松地处理这个问题。要将您的 Java 列表转换为 RDF 集合,您可以执行以下操作:

// starting node of the RDF collection
Resource head = valueFactory.createBNode();
// convert our list and add it to a newly-created Model
Model collection = RDFCollections.asRDF(objects, head, new LinkedHashModel());

这里collection只是一个 RDF 模型(一组 RDF 语句),您可以像添加任何其他 RDF 数据一样将其添加到三元存储库中(有关在存储库中存储和检索时如何使用集合的更多提示,请参阅RDF4J 文档)。

要将 RDF 集合转换回 Java 列表(保留顺序):

List<Value> values = RDFCollections.asValues(collection, head, new ArrayList<Value>());

或者,如果您希望它们再次作为字符串对象列表返回:

List<String> values = new ArrayList<>();
RDFCollections.consumeValues(collection, head, v -> values.add(v.stringValue()));

编辑也可以使用 SPARQL 1.1 按顺序检索此类 RDF 集合项,尽管这并不简单。请参阅是否可以在 SPARQL 的 RDF 集合中获取元素的位置?一个好的解决方案。

尽管如此,停下来想想你是否真的需要以固定的顺序存储东西可能是个好主意。RDF 本质上是无序的,虽然 RDF 集合建模提供了一种机制,但将所有内容都存储为集合并不高效。

在最常见的情况下,顺序实际上并不是实际数据模型的一部分,而是一个表示问题。在这些情况下,您可以在大多数情况下使用带有ORDER BY子句的 SPARQL 查询来对查询结果进行排序。

于 2020-04-08T01:03:12.613 回答
1

该用例似乎不太适合 RDF 模型。由于 RDF 描述了一个图,它的边的顺序并不重要。

话虽如此,针对您的特定用例的一个简单解决方案可能是例如使用具有两个额外 RDF 属性:order和的具体节点:value

RDF:

:subj :pred [:order 1; :value 'o1']. 
:subj :pred [:order 2; :value 'o2']. 
:subj :pred [:order 3; :value 'o3'].

SPARQL:

SELECT ?s ?p ?o {
  ?s ?p [:order ?order; :value ?o]
} ORDER BY ?order
于 2020-04-07T19:17:20.853 回答