多个 SELECT 查询以获取给定根的所有子项

Multiple SELECT query for getting all children of a given root

我想定义与用户兴趣相对应的根类别。然后我需要 return 给定根目录下的所有其他潜在兴趣。 我尝试了以下查询,但看起来它进入了一个循环(查询在内部执行)。

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX owl: <http://www.myweb.com/myontology.owl#> 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?user ?othercat
WHERE
{
    ?othercat rdfs:subClassOf ?root .
    {
      SELECT ?user ?retailcat ?root
      WHERE {
              ?user rdf:type owl:User . 
              ?user owl:hasUserProfile ?userprofile . 
              ?userprofile rdf:type owl:UserProfile . 
              ?userprofile owl:interestedIn ?retailcat . 
              ?entity rdf:type ?type .
              ?type rdfs:subClassOf* ?retailcat .
              ?retailcat rdfs:subClassOf ?root .
      }
    }
}

的确,当我执行子查询时,它工作正常,但是return用户当前的兴趣,没有提供同根的其他子概念的信息。

如何解决这个问题?

I tried the following query, but it looks like it enters into a loop (the query is executing internally).

SPARQL 查询不应该有进入循环的方法。首先执行子查询,然后执行封闭查询。没有办法重新执行内部部分或类似的东西。 (当然,查询可能会很昂贵并且需要很长时间,但这不是循环,原则上仍然是有界的。)

顺便说一句,使用 owl: 作为标准 OWL 命名空间以外的东西的前缀有点令人困惑,并且可能会在其他开发人员看到您的查询时误导他们。它本身并没有什么不对,但您可能要考虑为您的命名空间使用不同的前缀。

您的查询中确实有一部分会使事情变得相当昂贵。你有模式

?entity rdf:type ?type .
?type rdfs:subClassOf* ?retailcat .

其中 ?entity 没有连接到任何其他东西,也没有 在其他任何地方使用 。这意味着您将为 ?entity 的每个可能值都有一个子查询解决方案,这仅意味着您将结果数乘以 [=37 的可能值数=]?entity.

如果我理解您的查询,您是在尝试从用户感兴趣的类别开始,在类别树中向上找到一些根概念,然后在该根下找到其他类别。您实际上不需要子查询;您可以使用非嵌套查询来完成:

select ?user ?othercat {
    ?user rdf:type owl:User . 
    ?user owl:hasUserProfile ?userprofile . 
    ?userprofile rdf:type owl:UserProfile . 
    ?userprofile owl:interestedIn ?retailcat . 
    ?retailcat rdfs:subClassOf ?root .
    ?othercat rdfs:subClassOf ?root .
}

这将找到 ?othercat 的值,这些值是 ?retailcat 的兄弟姐妹,以及 ?retailcat 本身。如果你想避免?retailcat,你可以添加

filter(?othercat != ?retailcat)

但这应该不会对性能产生太大影响;这只是一个要过滤掉的结果。

您可能要考虑的唯一其他因素是,您并没有真正找到具有 rdfs:subClassOf 的类别树的 "root";你只是上升了一个层次。例如,如果您的类别树看起来像

  • 汽车
    • SUV
    • 跑车
      • 克尔维特
      • 野马

并且用户对 Mustang 感兴趣,那么您将转到 SportsCar 并找到 Corvette,但你不会在树上走得更远。 (如果您有可用的推理,您实际上可能会在树上走得更远,但我暂时假设您没有。)要沿着树上的子类链接,您可以添加 * 到跟随链的路径:

?retailcat rdfs:subClassOf* ?root .
?othercat rdfs:subClassOf ?root .

然后您将获得树中的所有 类(除了最顶层的 Automobile)。