使用包含 owl:sameAs 三元组的 SPARQL 本体进行查询时避免计数爆炸

Avoiding count explosion in querying with SPARQL ontologies containing owl:sameAs triples

我正在尝试构建一个(本地)ontology 来描述有限数量的对象,并通过 owl:sameAs 谓词将这些对象链接到外部资源。然而,当我简单地查询那种对象的数量时,我得到的是所描述对象的两倍。很明显,外部资源也是独立计算的,因为考虑的是 URI 的数量,而不是不同对象的数量。 我已经通过以下方式解决了这个问题:我假设本地 ontology 可以被看作是一个 "reference hub" 用于了解这些对象的基本内容,所以我 select 的所有对象某种,然后只过滤掉那些包含本地 ontology 的基本 URI,即:

# How many objects are there?

PREFIX ch: <http://www.example.com/ontologies/domain#>

SELECT (COUNT(DISTINCT ?elem) AS ?count) WHERE {
?elem a ch:Element.
FILTER (REGEX (STR(?elem) ,"http://www.example.com/ontologies/domain") ).
}

但是,我对这种做法有两个顾虑:

1) 它看起来有点乱(即使在某种程度上是有原则的),而我想要一些更合乎逻辑的东西

2) 感觉这个查询效率不是很高

我在这里和 google 上搜索了很多,但没有找到更好的解决方案...这里有什么建议吗?

非常感谢您的帮助!

GROUP BY 代表元素

如果有一些 属性 应该对每个人都有不同的值,那么您可以使用它来强加您需要的 "equivalent class" 结构。例如,像这样:

prefix ch: <http://www.example.com/ontologies/domain#>

select (count(?label) as ?count) where {
  ?elem a ch:element ;
        rdfs:label ?label .
}
group by ?label

合成一个有代表性的元素

如果等价 class 中的所有元素不共享一个值,您仍然可以通过请求每个等价项中的最小元素 class。我们可以使用元素的 IRI 来对元素进行排序,并将其用于 select 一个 unique 个体。这确实假定每个 ?elem 和它相同的所有事物在 str 函数(和 IRIs 做的)下具有明确定义的行为。

prefix ch: <http://www.example.com/ontologies/domain#>

select (count(distinct ?elem) as ?count) where {
  ?elem a ch:element .
  filter not exists {
    ?elem (owl:sameAs|^owl:sameAs)* ?elem_
    filter( str(?elem_) < str(?elem) )
  }
}