使用 ORDER BY 和 GROUP BY 的 SPARQL CONTRUCT 有序列表
SPARQL CONTRUCT ordered list with ORDER BY and GROUP BY
尊敬的 RDF/SPARQL 社区,
我的目标是通过SPARQL构建一个按产品分组并按时间排序的有序列表,以显示产品的轨迹。我正在使用 GraphDB,“scmon”是我的习惯 ontology。以下是详细信息:
我存储了包含产品时间戳 (scmon:atTime
) 和位置 (scmon:atLocation
) 的 RDF 数据。在 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> .
如您所见,每个 track
条目都通过 scmon:positionOf
关系分配给 product
。
我现在的目标是通过 SPARQL 构建一个按产品分组并按时间排序的有序列表,以类似于以下形式显示产品的轨迹:
<product1> scmon:hasPosSequence <track5>
<track5> scmon:nextPosition <track6>
<track6> scmon:nextPosition <track7>
<track7> scmon:nextPosition NULL
<product2> ...
这种方法的灵感来自 W3C 示例模式 2 的 n 元关系(https://www.w3.org/TR/swbp-n-aryRelations/#pattern2) which looks like this: https://www.w3.org/TR/swbp-n-aryRelations/flight_example.jpg
我的自定义 ontology 前缀 scmon
也采用了建议的结构(具有类似的命名 类 和关系),看起来像这样 https://www.w3.org/TR/swbp-n-aryRelations/flight_classes.jpg
我能够为 <scmon:hasPosSequence>
构造第一个 relation/line,它从乘积 ?product
指向 [=22= 找到的第一个位置 ?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
}
}
...但是我该如何继续呢?我尝试了一些 SPARQL SELECT 查询来测试我是否可以 select 构建 scmon:nextPosition
关系所需的信息,但没有成功。
这种模式可以构建吗?或者我是否必须以某种方式更改我的初始 RDF 数据模型?
提前感谢任何提示!
这样:
PREFIX scmon: <http://www.semanticweb.org/sildop/ontologies/2020/scmon#>
CONSTRUCT {
?product scmon:hasPosSequence ?track0 .
?track1 scmon:nextPosition ?track3
} WHERE {
?track1 scmon:positionOf ?product ; scmon:atTime ?time1 .
OPTIONAL {
?track2 scmon:positionOf ?product ; scmon:atTime ?time2 .
FILTER (?time2 > ?time1)
FILTER NOT EXISTS {
?track_ scmon:positionOf ?product ; scmon:atTime ?time_
FILTER (?time_ > ?time1 && ?time_ < ?time2)
}
}
BIND (COALESCE(?track2, scmon:NULL, ?track2) AS ?track3)
?track0 scmon:positionOf ?product ; scmon:atTime ?time0 .
FILTER NOT EXISTS {
?track_ scmon:positionOf ?product ; scmon:atTime ?time_
FILTER (?time_ < ?time0)
}
}
顺便说一下,如果您需要对职位进行编号,请尝试以下操作:
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,见this discussion。如果您真的希望它们被明确表示,您可以使用以 rdf:nil
.
结尾的 rdf:List
s
尊敬的 RDF/SPARQL 社区,
我的目标是通过SPARQL构建一个按产品分组并按时间排序的有序列表,以显示产品的轨迹。我正在使用 GraphDB,“scmon”是我的习惯 ontology。以下是详细信息:
我存储了包含产品时间戳 (scmon:atTime
) 和位置 (scmon:atLocation
) 的 RDF 数据。在 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> .
如您所见,每个 track
条目都通过 scmon:positionOf
关系分配给 product
。
我现在的目标是通过 SPARQL 构建一个按产品分组并按时间排序的有序列表,以类似于以下形式显示产品的轨迹:
<product1> scmon:hasPosSequence <track5>
<track5> scmon:nextPosition <track6>
<track6> scmon:nextPosition <track7>
<track7> scmon:nextPosition NULL
<product2> ...
这种方法的灵感来自 W3C 示例模式 2 的 n 元关系(https://www.w3.org/TR/swbp-n-aryRelations/#pattern2) which looks like this: https://www.w3.org/TR/swbp-n-aryRelations/flight_example.jpg
我的自定义 ontology 前缀 scmon
也采用了建议的结构(具有类似的命名 类 和关系),看起来像这样 https://www.w3.org/TR/swbp-n-aryRelations/flight_classes.jpg
我能够为 <scmon:hasPosSequence>
构造第一个 relation/line,它从乘积 ?product
指向 [=22= 找到的第一个位置 ?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
}
}
...但是我该如何继续呢?我尝试了一些 SPARQL SELECT 查询来测试我是否可以 select 构建 scmon:nextPosition
关系所需的信息,但没有成功。
这种模式可以构建吗?或者我是否必须以某种方式更改我的初始 RDF 数据模型?
提前感谢任何提示!
这样:
PREFIX scmon: <http://www.semanticweb.org/sildop/ontologies/2020/scmon#>
CONSTRUCT {
?product scmon:hasPosSequence ?track0 .
?track1 scmon:nextPosition ?track3
} WHERE {
?track1 scmon:positionOf ?product ; scmon:atTime ?time1 .
OPTIONAL {
?track2 scmon:positionOf ?product ; scmon:atTime ?time2 .
FILTER (?time2 > ?time1)
FILTER NOT EXISTS {
?track_ scmon:positionOf ?product ; scmon:atTime ?time_
FILTER (?time_ > ?time1 && ?time_ < ?time2)
}
}
BIND (COALESCE(?track2, scmon:NULL, ?track2) AS ?track3)
?track0 scmon:positionOf ?product ; scmon:atTime ?time0 .
FILTER NOT EXISTS {
?track_ scmon:positionOf ?product ; scmon:atTime ?time_
FILTER (?time_ < ?time0)
}
}
顺便说一下,如果您需要对职位进行编号,请尝试以下操作:
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,见this discussion。如果您真的希望它们被明确表示,您可以使用以 rdf:nil
.
rdf:List
s