【问题标题】:Selecting some distinct and some not-distinct tags in SPARQL在 SPARQL 中选择一些不同的和一些不不同的标签
【发布时间】:2011-07-20 17:50:22
【问题描述】:

我正在尝试向 DBPedia 查询与本体中给定类相关的属性列表,但由于人类可读的“标签”并不总是很清楚,我还想提供一个示例数据库。问题是,虽然我想选择所有不同的属性,但我只想要每个属性的一个示例。 Here's 在不捕获示例的情况下我的查询看起来如何:

SELECT DISTINCT ?prop ?title WHERE {
    ?thing ?prop [].
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} ORDER BY DESC(COUNT(DISTINCT ?thing))
LIMIT 100

如果我在 this way 中更改它,我会开始得到 ?prop 的重复值:

SELECT DISTINCT ?prop ?title ?example WHERE {
    ?thing ?prop ?example.
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} ORDER BY DESC(COUNT(DISTINCT ?thing))
LIMIT 100

我对使用 SPARQL 和一般的数据库查询非常陌生,所以我完全不清楚如何执行此操作。理想情况下,我会有类似 DISTINCT(?prop) ?title ?example 的东西,它为 prop 选择每个唯一值,并返回其标题和示例。

【问题讨论】:

    标签: distinct rdf sparql dbpedia


    【解决方案1】:

    如果您不关心示例但关心速度,SAMPLE 可以比GROUP BY 快得多

    SELECT ?prop (SAMPLE(?title) AS ?title) (SAMPLE(?example) AS ?example) 
    WHERE {
        ?thing ?prop ?example.
        ?thing a <http://dbpedia.org/ontology/Currency>.
        ?prop rdf:type rdf:Property.
        ?prop rdfs:label ?title.
    } LIMIT 100
    

    你可能不会注意到 dbpedia 上的差异,因为它缓存了查询结果,但我注意到使用其他端点时有很大的不同。

    我在创建查询多个 sparql 端点的自动完成服务时遇到了同样的问题。我需要找到与搜索词相关的单个链接,其中链接本身并不是很重要,但查询的速度非常很重要。

    【讨论】:

      【解决方案2】:

      以下是使用子查询实现您想要的另一种方法:

      SELECT ?prop ?title ?example 
      WHERE 
      {
          ?thing a <http://dbpedia.org/ontology/Currency>.
          ?prop rdf:type rdf:Property.
          { SELECT ?title ?example WHERE { ?thing ?prop ?example . ?prop rdfs:label ?title. } LIMIT 1 }
      }
      LIMIT 100
      

      这样做的好处是它符合 SPARQL 1.1 标准,正如我在评论中所述,标准不允许按聚合排序,因此您使用的是供应商特定的扩展,这将限制查询的可移植性。

      如果您确实想以可跨 SPARQL 1.1 实现移植的方式按聚合值排序,那么您必须首先像这样进行投影:

      SELECT ?s (COUNT(?p) AS ?predicates) WHERE
      {
        ?s ?p ?o
      } GROUP BY ?s ORDER BY DESC(?predicates)
      

      【讨论】:

        【解决方案3】:

        在您的第二个查询中, distinct 应用于 ?prop ?title?example 的值的组合。因此,您不会得到任何重复项,例如在第二个查询中获得的以下两行:

        dbpedia2:subunitName    "subunit name "@en  "cent"@en
        dbpedia2:subunitName    "subunit name "@en  "centavo"@en
        

        它们不是重复的,因为第三行 ?example 有两个不同的值 "cent"@en"centavo"@en

        解决此问题的一种可能方法是使用GROUP BYMIN 来获得?label?example 的最低排名值,即:

        SELECT ?prop MIN(?title) MIN(?example) WHERE {
            ?thing ?prop ?example.
            ?thing a <http://dbpedia.org/ontology/Currency>.
            ?prop rdf:type rdf:Property.
            ?prop rdfs:label ?title.
        } GROUP BY ?prop
        

        【讨论】:

        • 这很好用,但是 GROUP BY 参数是否必要?我已经用 ORDER BY DESC(COUNT(DISTINCT ?thing)) 实现了它,它似乎仍然有效。是否存在 ORDER BY 会产生一些令人不快的结果而 group by 不会产生的情况?
        • @Paul 要成为正确有效的查询,您不能直接按聚合排序 - SPARQL 1.1 规范不允许这样做。这可能是一个 Virtuoso 扩展,并且会使查询不可移植,即它不一定适用于非 Virtuoso 端点。请参阅我的答案,了解应该做同样事情且可移植的替代查询表单
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-23
        • 1970-01-01
        • 2021-12-29
        • 1970-01-01
        • 2020-12-18
        • 2020-06-16
        • 1970-01-01
        相关资源
        最近更新 更多