当前位置: 首页 > 面试题库 >

SPARQL:返回指定或等效类满足的所有交点

贲铭
2023-03-14
问题内容

如果我将ABC和CDE类定义为A,B,C,D,E类的交集,如下所示:

<Class rdf:about="&blah;ABC">
    <equivalentClass>
        <Class>
            <intersectionOf rdf:parseType="Collection">
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;A"/>
                </Restriction>
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;B"/>
                </Restriction>
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;C"/>
                </Restriction>
            </intersectionOf>
        </Class>
    </equivalentClass>
</Class>

<Class rdf:about="&blah;CDE">
    <equivalentClass>
        <Class>
            <intersectionOf rdf:parseType="Collection">
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;C"/>
                </Restriction>
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;D"/>
                </Restriction>
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;E"/>
                </Restriction>
            </intersectionOf>
        </Class>
    </equivalentClass>
</Class>

如何查询SPARQL中给定的一组输入类满足其限制的所有交叉点类?例如,如果我将A,B,C,D,E,F,G输入到此查询中,那么我希望可以返回

ABC A
    B
    C
CDE C
    D
    E

还有两个皱纹:如果我查询A,Z,C,其中Z是B的等价类,那么这应该匹配并理想地返回

ABC A
    Z
    C

其次,结果应仅返回最大匹配项;因此,如果存在一个类ABCD,并且我在A,B,C,D中进行查询,它将返回ABCD而不是ABC。

提前致谢!

更新:

为了明确起见,除非所有构成类都在提供的输入列表中,否则我不希望与交集类匹配。例如,如果我向查询提供A,B,则我不希望取回ABC。如果我提供A,B,C,D,我确实想找回ABC。

我的用例是这样的:我有一组数据点,在每个数据点中,我标识出一些任意的基本概念A,B,C,D
…等,每个概念都有不同的可能性。我想问本体论“此列表包含哪些更高层次的概念(即交叉点)?”

当前,我的查询如下所示(考虑了我上面概述的本体中的限制和onProperty):

SELECT DISTINCT ?intclass ?inputclasses
WHERE
{
  ?intclass owl:equivalentClass /
    owl:intersectionOf /
    rdf:rest*/rdf:first /
    owl:someValuesFrom ?inputclasses
}
ORDER BY ?intclass
BINDINGS ?inputclasses { (:A) (:B) (:C) (:D) }

不幸的是,这会返回我的本体中包含任何输入类的每个交集。我猜想这是因为其余/首先根据输入列表评估路口的每个构成类,并在找到它们的任何一个时进行匹配。

我想做的是 (a) 仅在输入列表中存在相交的所有类时进行匹配, (b) 从与输入列表中的类等效的类中推断匹配项,并且 (c)
返回相交类以及与之匹配的输入列表中的类子集。也许通过SPARQL这是行不通的吗?


问题答案:

首先,我认为您无法完全按照自己的意愿去做,但是我认为您可以做到相当接近。特别是,我认为您提到的最大约束将特别难以实现。以这种方式处理SPARQL中的事物通常很困难。尽管如此,我们可以看到我们能做什么。

要处理的数据

用我们可以实际使用的一些样本数据来回答这类问题要容易得多。我也从简化问题开始,以便ABC只是A,B和C以及C,D和E的CDE的交集。目前还没有限制类(它们不会增加太多的复杂性,其实)。为了进行测试(能够确保我们的查询不会返回不需要的值),我还添加了类F和DEF。在Turtle序列化中查看数据也更加容易,因为它更接近于SPARQL模式语法。这是简化的本体:

@prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<http://stackoverflow.com/q/22396095/1281433/intersections>
        a       owl:Ontology .

:A      a       owl:Class .
:B      a       owl:Class .
:C      a       owl:Class .
:D      a       owl:Class .
:E      a       owl:Class .
:F      a       owl:Class .

:ABC    a                    owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( :A :B :C )
                             ] .

:CDE    a                    owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( :C :D :E )
                             ] .

:DEF    a                    owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( :D :E :F )
                             ] .

查找类的交集

对于每个相当于一个交集类的类,从类到每个相交的类都有一条路径。我们可以利用这一事实找到与包括A,B和C的交集等效的任何类:

prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#>
prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix xsd:   <http://www.w3.org/2001/XMLSchema#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select distinct ?class where {
  ?class owl:equivalentClass/
         owl:intersectionOf/
         rdf:rest*/rdf:first :A, :B, :C .
}



---------
| class |
=========
| :ABC  |
---------

但是,找不到CDE,因为此查询正在询问具有 所有
指定值的东西。听起来,您想要的是询问至少具有某些指定值之一且没有非指定值的事物。您可能需要两次编写类列表,但是您可以这样做:

prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#>
prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix xsd:   <http://www.w3.org/2001/XMLSchema#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?class ?i where {
  values ?i { :A :B :C :D :E }
  ?class owl:equivalentClass/
         owl:intersectionOf/
         rdf:rest*/rdf:first ?i .

  filter not exists { 
    ?class owl:equivalentClass/
           owl:intersectionOf/
           rdf:rest*/rdf:first ?j .
    filter( !(?j in (:A, :B, :C, :D, :E )) )
  }
}
order by ?class ?i



--------------
| class | i  |
==============
| :ABC  | :A |
| :ABC  | :B |
| :ABC  | :C |
| :CDE  | :C |
| :CDE  | :D |
| :CDE  | :E |
--------------

请注意,DEF不在结果中,因为尽管它确实具有D和E,但它的值也不是任何指定的类F。

由于我们筛选出了这是一个元素每个路口类 输入列表中,我们保证每个路口类,我们 保留唯一 的元素
在输入列表中。有了这样的措辞,我们实际上可以使查询更简单:

prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?class ?i where {
  # find each ?class that's equivalent to an intersection
  ?class owl:equivalentClass/owl:intersectionOf ?list .

  # and grab the intersecting classes for the results
  ?list rdf:rest*/rdf:first ?i .

  # but filter out any ?class that has an intersecting
  # class that's not in the input list.
  filter not exists { 
    ?list rdf:rest*/rdf:first ?element .
    filter( !(?element in (:A, :B, :C, :D, :E )) )
  }
}



--------------
| class | i  |
==============
| :ABC  | :A |
| :ABC  | :B |
| :ABC  | :C |
| :CDE  | :C |
| :CDE  | :D |
| :CDE  | :E |
--------------

但是,这可能会效率较低,因为现在您要查找 每个 路口类别并过滤掉不合格的路口类别,而不是只查找 可能
可接受的路口类别,然后过滤掉一些路口类别。这可能有多重要,取决于您的实际数据。

我认为这可以回答您问题的主要部分。要使用限制的交叉点,您只需要注意所讨论的类之间的路径有些不同。您想要匹配owl:someValuesFrom列表元素的属性值,而不是匹配列表中的元素,因此路径需要一个final
owl:someValuesFrom

?class owl:equivalentClass/
       owl:intersectionOf/
       rdf:rest*/rdf:first/
       owl:someValuesFrom ?i .

超越这个

处理其他等效项

如果我查询A,Z,C,其中Z是B的等价类,那么这应该匹配并理想地返回

ABC A
    Z
    C

这里的查询开始变得有点复杂,但仍然可以管理。诀窍在于?i,您需要选择?i与交集列表的元素等效的列表作为输入的成员,而不是选择交集列表的简单成员。然后,过滤
交叉点也变得更加复杂。您需要确保 存在 任何 元素,以使输入列表中 没有
与交集元素等效的元素。将所有内容放在一起,您将得到以下查询:

prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?class ?i where {
  ?class owl:equivalentClass/
         owl:intersectionOf ?list .
  ?list rdf:rest*/rdf:first/(owl:equivalentClass|^owl:equivalentClass)* ?i .
  filter( ?i in (:A, :B, :C, :D, :E ))

  filter not exists { 
    ?list rdf:rest*/rdf:first ?element .
    filter not exists {
      ?element (owl:equivalentClass|^owl:equivalentClass)* ?j
      filter( ?j in (:A, :B, :C, :D, :E ))
    }
  }
}

如果添加以下数据

:Z      a       owl:Class ;
        owl:equivalentClass :B .

:AZC    a                    owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( :A :Z :C )
                             ] .

那么您将得到以下结果:

--------------
| class | i  |
==============
| :ABC  | :A |
| :ABC  | :B |
| :ABC  | :C |
| :AZC  | :A |
| :AZC  | :B |
| :AZC  | :C |
| :CDE  | :C |
| :CDE  | :D |
| :CDE  | :E |
--------------

这可能不太难(尽管获取最终查询会有些棘手)。重要的是,等效类将通过路径关联(owl:equivalentClass|^owl:equivalentClass)*

最佳结果

其次,结果应仅返回最大匹配项;因此,如果存在一个类ABCD,并且我在A,B,C,D中进行查询,它将返回ABCD而不是ABC。

如果您能做到的话,这部分可能会很难。SPARQL实际上并非旨在处理这种查询。计算相交类相交的类的数量很容易,但是如果可以的话,比较那些集的子集关系将非常困难。



 类似资料:
  • 返回数组中所有 val 的索引。 如果 val 从不出现,则返回 [] 。 使用 Array.forEach() 循环元素和 Array.push() 来存储匹配元素的索引。 返回索引数组。 const indexOfAll = (arr, val) => { const indices = []; arr.forEach((el, i) => el === val && indices.

  • 希望我不会把事情搞复杂。我编写了以下SQL,返回用户他们最近的事务满足一个条件(TRANS_TYPE NOT IN(4,6,21,23)或DESTORIT_OPTION&64<>64)。 我通过使用 前面代码中的sub查询将返回所有用户的所有事务,并按DESC顺序对其进行排序,外部SELECT将通过检查rank 1事务来显示满足条件的用户。 我想要的是像这样的东西 FOREACH user如果用户

  • 我正在写一些代码,有些事情让我困惑。我有一个名为的数字数组。现在我想遍历这个列表,如果一个值高于60,例如,我想创建一个新的对象数组(集合),在那里我们存储高值,它的索引来自原始数组。所以以下面的代码为例 控制台。日志输出如下 这个输出是我所需要的,但是如何防止返回未定义的值呢?我考虑过使用数组。但这似乎不合适?我应该使用不同的数组方法吗?我不想使用for循环并推送到一个新数组,除非这是在不返回未

  • web3.eth.getTransactionReceipt()方法返回指定交易的收据对象。 如果交易处于pending状态,则返回null。 调用: web3.eth.getTransactionReceipt(hash [, callback]) 参数: hash:String - 交易的哈希值 callback:Function - 可选的回调函数,其第一个参数为错误对象,第二个参数为结果

  • web3.eth.getTransaction()方法返回具有指定哈希值的交易对象。 调用: web3.eth.getTransaction(transactionHash [, callback]) 参数: transactionHash:String - 交易的哈希值 callback:Function - 可选的回调函数,其第一个参数为错误对象,第二个参数为返回结果。 返回值: 一个Pro

  • 问题内容: 我是MySql的新手,所以请保持谦虚。 Oracle 中的子句或MySQL中的SQL Server中的表是否等效?我想做的是以下几点: 从表A删除一组行 将已删除的行集插入表B。 请帮忙! 谢谢 问题答案: 不幸的是,您不能在 一个查询中 同时进行插入和删除 操作 ,但是如果您使用的是事务存储引擎(例如InnoDB),则可以在一个 事务中 完成所有操作。此外,它受Oracle和Post