SPARQL使用ORDER BY和GROUP BY构造有序列表

SPARQL使用ORDER BY和GROUP BY构造有序列表,sparql,rdf,graphdb,Sparql,Rdf,Graphdb,尊敬的RDF/SPARQL社区: 我的目标是通过SPARQL构建一个按产品分组、按时间排序的有序列表,以显示产品的轨迹。我正在使用GraphDB,“scmon”是我的自定义本体。详情如下: 我存储的RDF数据包含产品的时间戳(scmon:atTime)和位置(scmon:atLocation)。在Turtle语法中,它如下所示: @base <http://example/base/testtracks> . @prefix xsd: <http://www.w3.org/20

尊敬的RDF/SPARQL社区:

我的目标是通过SPARQL构建一个按产品分组、按时间排序的有序列表,以显示产品的轨迹。我正在使用GraphDB,“scmon”是我的自定义本体。详情如下:

我存储的RDF数据包含产品的时间戳(
scmon:atTime
)和位置(
scmon:atLocation
)。在Turtle语法中,它如下所示:

@base <http://example/base/testtracks> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix scmon: <http://www.semanticweb.org/sildop/ontologies/2020/scmon#> .

<tracks5> a scmon:NetPosition;
  scmon:atTime "2018-12-10T14:48:59Z"^^xsd:dateTimeStamp;
  scmon:atLocation <5>;
  scmon:positionOf <product1> .

<tracks6> a scmon:NetPosition;
  scmon:atTime "2018-12-12T13:37:19Z"^^xsd:dateTimeStamp;
  scmon:atLocation <5002>;
  scmon:positionOf <product1> .

<tracks7> a scmon:NetPosition;
  scmon:atTime "2018-12-13T19:46:00Z"^^xsd:dateTimeStamp;
  scmon:atLocation <2>;
  scmon:positionOf <product1> .

<tracks17> a scmon:NetPosition;
  scmon:atTime "2018-12-10T14:48:59Z"^^xsd:dateTimeStamp;
  scmon:atLocation <4953>;
  scmon:positionOf <product2> .

<tracks18> a scmon:NetPosition;
  scmon:atTime "2018-12-12T13:37:19Z"^^xsd:dateTimeStamp;
  scmon:atLocation <4953004195>;
  scmon:positionOf <product2> .

<tracks19> a scmon:NetPosition;
  scmon:atTime "2018-12-13T19:46:00Z"^^xsd:dateTimeStamp;
  scmon:atLocation <4176>;
  scmon:positionOf <product2> .
这种方法的灵感来自W3C n元关系的示例模式2(),如下所示:

另外,我的前缀为
scmon
的自定义本体修改了建议的结构(具有类似的命名类和关系),如下所示

我能够为
构建第一个关系/行,该关系/行指向从产品
?产品
(min(?time))
找到的第一个位置
?netPos

PREFIX scmon: <http://www.semanticweb.org/sildop/ontologies/2020/scmon#>
CONSTRUCT {?product scmon:hasPosSequence ?netPos}
where {
    {
    ?product ^scmon:positionOf ?netPos .
    ?netPos scmon:atTime ?startTime .
    }
    {
                select ?product (min(?time) as ?startTime)
                where {
                    ?netPos scmon:positionOf ?product .
                    ?netPos scmon:atTime ?time .
                } group by ?product 
            }
        }
前缀scmon:
构造{?产品scmon:hasposequence?netPos}
在哪里{
{
?产品^scmon:netPos的位置。
netPos scmon:开始时间?开始时间。
}
{
选择?产品(分钟(?时间)作为?开始时间)
在哪里{
?netPos scmon:产品的位置。
netPos scmon:时间。
}分组副产品
}
}
……但我怎么能从那里继续下去呢?我尝试了一些SPARQL SELECT查询来测试是否可以选择构造
scmon:nextPosition
关系所需的信息,但没有成功

有可能构建这种模式吗?还是我必须以某种方式更改我的初始RDF数据模型

提前感谢您的任何提示

这样:

前缀scmon:
构造{
?产品序列号:hasposequence?track0。
?track1 scmon:下一个位置?track3
}在哪里{
?track1 scmon:产品的位置;scmon:时间1。
可选的{
?track2 scmon:产品的位置;scmon:时间2。
过滤器(?时间2>时间1)
筛选器不存在{
跟踪:产品的位置;跟踪:时间_
过滤器(?时间>时间1和时间>时间2)
}
}
绑定(合并(?track2,scmon:NULL,?track2)为?track3)
?track0 scmon:产品的位置;scmon:时间?时间0。
筛选器不存在{
跟踪:产品的位置;跟踪:时间_
过滤器(?时间<?时间0)
}
}
顺便说一下,如果您需要对位置进行编号,请尝试以下操作:

SELECT ?product ?track (COUNT(?track_) AS ?position) {
  ?track scmon:positionOf ?product ;  scmon:atTime ?time .
  ?track_ scmon:positionOf ?product ;  scmon:atTime ?time_
  FILTER (?time >= ?time_)                         
} GROUP BY ?product ?track ORDER BY ?product ?position

对于RDF中的
NULL
s,请参阅。如果您真的希望它们被明确地表示出来,您可以使用
rdf:List
s,它以
rdf:nil
结尾

非常感谢您的帮助和rdf中关于
Null
的提示!我想我不需要明确地使用它们:我的本体存储了
跟踪
:nextPosition max 0
基数被分类为
FinalTrack
的信息。我认为
Null
相当于
max 0
基数,它告诉推理机推断
轨迹是
FinalTrack
。。。现在我知道我的假设是错误的。如果使用SHACL验证来测试基数是否遵守,是否会出现这种情况?@SilviD,
max 0
由于开放世界假设而存在问题;如果GraphDB支持,您可以使用SHACL规则:哦,我明白了-谢谢。对于遇到相同问题的任何人:GraphDB(9.5)的用户文档说它支持SHACL验证
SELECT ?product ?track (COUNT(?track_) AS ?position) {
  ?track scmon:positionOf ?product ;  scmon:atTime ?time .
  ?track_ scmon:positionOf ?product ;  scmon:atTime ?time_
  FILTER (?time >= ?time_)                         
} GROUP BY ?product ?track ORDER BY ?product ?position