在语义网络图中,我有一组主题(S1,S2,...,Sn)和一组谓词(P1,P2,...,Pn)。我想基于它们的谓词对实例进行分组(即选择具有相同谓词集的所有实例,而不管对象值如何)。
例如,如果我有
S1 P1 v1.
S1 P2 v2.
S2 P3 v3.
S2 P4 v4.
S3 P1 v5.
S3 P2 v6.
我希望有两组{S1,S3}和{S2}。 我自己生成图表,所以我可以改变它的结构,如果它有助于实现这个要求。
答案 0 :(得分:2)
这比听起来有点复杂,我不完全确定它是否可以完全通用,但我认为你可以在大多数端点实现这一点。如果要基于主题具有的谓词的 set 进行分组,那么首先需要能够获得主题所具有的谓词的 set ,并且一种可以与其他谓词集进行比较的方法。 SPARQL没有设置值数据类型的概念,但使用 group_concat 和 distinct ,您可以获得包含所有谓词的字符串,如果您使用 order by 当您选择它们时,大多数端点都会保持订单不变,因此 group_concat 字符串基本上是规范的。 但是,据我所知,该行为并非由规范保证。
@prefix : <urn:ex:>
:S1 :P1 :v1 .
:S1 :P2 :v2 .
:S2 :P3 :v3 .
:S2 :P4 :v4 .
:S3 :P1 :v5 .
:S3 :P2 :v6 .
prefix : <urn:ex:>
#-- The behavior in most (all?) endpoints seems to be
#-- to preserve the order during the group_concat
#-- operation, so you'll get "noramlized" values
#-- for ?preds. I don't think is *guaranteed*, though.
select ?s (group_concat(?p) as ?preds) where {
#-- get the values of ?s and ?p and ensure that
#-- they're in some kind of standarized order.
#-- Just ordering by ?p might be fine, too.
{ select distinct ?s ?p {
?s ?p ?o
}
order by ?p
}
}
group by ?s
-------------------------------
| s | preds |
===============================
| :S2 | "urn:ex:P3 urn:ex:P4" |
| :S3 | "urn:ex:P1 urn:ex:P2" |
| :S1 | "urn:ex:P1 urn:ex:P2" |
-------------------------------
现在你只需要更进一步,将这些结果分组为?preds:
prefix : <urn:ex:>
select (group_concat(?s) as ?subjects) {
select ?s (group_concat(?p) as ?preds) where {
{ select distinct ?s ?p {
?s ?p ?o
}
order by ?p
}
}
group by ?s
}
group by ?preds
-------------------------
| subjects |
=========================
| "urn:ex:S1 urn:ex:S3" |
| "urn:ex:S2" |
-------------------------