【问题标题】:Sparql Keys vs distinct valuesSparql 键与不同的值
【发布时间】:2012-07-10 18:42:32
【问题描述】:

我有一个返回重复项的 sparql 查询,我希望它仅在其中一个值(subjectID)上清理它们。与 DISTINCT 不同,它似乎为所选值的组合找到唯一值,而不是只为其中一个参数。 我在这里看到有人提出 group by,但这似乎只有在我列出 group by 之后的所有参数时才适用(我的 sparql 端点抱怨,例如 SELECT 中的非组键变量:?职业)。 我尝试运行内部选择,但它似乎不适用于这个特定的查询。那么可能是查询本身的问题(liveIn 可选的值似乎导致了重复)?

虽然在 SPARQL 学习曲线的早期阶段对关系数据库感到满意,但请随时为不熟悉的人解释显而易见的事情! :)

select distinct  
  ?subjectID ?englishName ?sex ?locatedIn15Name 
  ?dob ?dod ?dom ?bornLocationName ?occupation 
  where { 
      ?person a hc:Person ;
      hc:englishName ?englishName ;
      hc:sex ?sex; 
      hc:subjectID ?subjectID; 
       optional { ?person hc:livedIn11 ?livedIn11 .
           ?livedIn11 hc:englishName ?lived11LocationName . 
           ?livedIn11 hc:locatedIn11 ?locatedIn11 .
           ?locatedIn11 hc:englishName ?locatedIn11Name .
           ?locatedIn11 hc:locatedIn15 ?locatedIn15 .
 ?locatedIn15 hc:englishName ?locatedIn15Name .
 } . 
       optional {?person hc:born ?dob } .
       optional {?person hc:dateOfDeath ?dod } .
       optional {?person hc:dateOfMarriage ?dom } .
       optional { ?person hc:bornIn ?bornIn . 
       ?bornIn hc:englishName ?bornLocationName . 
             ?bornIn hc:easting ?easting . 
             ?bornIn hc:northing ?northing } .
       optional {  ?person hc:occupation ?occupation } 
       FILTER regex(?englishName, "^FirstName LastName")
      } 
  GROUP BY 
  ?subjectID ?englishName  ?sex 
   ?locatedIn15Name ?dob ?dod ?dom 
  ?bornLocationName ?occupation 

【问题讨论】:

    标签: sparql semantic-web


    【解决方案1】:

    回复错误信息:

    SELECT 中的非组键变量:?occupation

    您可以通过使用 SAMPLE() 聚合来避免这种情况 - 这将允许您只对 ?subjectID 进行分组,但仍然可以为其余变量选择值,前提是您只关心为其他变量获取一个值。

    这是一个简单的例子:

    SELECT ?subjectID (SAMPLE(?dob) AS ?dateOfBirth)
    WHERE
    {
      ?person a hc:Person ;
              hc:subjectID ?subjectID .
      OPTIONAL { ?person hc:born ?dob }
    }
    GROUP BY ?subjectID
    

    【讨论】:

    • 谢谢 Rob,这真的很方便!我猜这有点不确定采样,所以要谨慎使用? :)
    • @Jeen Broekstra 对我来说这是SAMPLE的主要目的
    • @Jeen Broekstra 我在答案 (answers.semanticweb.com/questions/17706/…) 上发布了一个关于此问题的问题 - 我很想知道您期望 SAMPLE 的使用方式
    【解决方案2】:

    首先要注意的是,在 RDF/SPARQL 中实际上没有键这样的东西。您正在查询一个图表,?subjectID 可能只是为您选择的其他变量提供了几种可能的值组合。这是由您查询的图形的形状引起的:也许您的人有多个英文名字,或者实际上相反:同一个英文名字可以由多个人共享。

    SPARQL SELECT 查询是一种奇怪的野兽:它查询图形结构,但将结果显示为一个平面表(从技术上讲,它是一组变量绑定的序列,但它相当于同一件事)。出现重复是因为您的变量值的不同组合可以通过基本上遵循图表中的不同路径来找到。

    因此,您在结果中得到 ?subjectID 的重复值是不可避免的,因为从 RDF 图的角度来看,这些是您查询的唯一解决方案。您无法在不实际丢失信息的情况下过滤掉结果,因此通常很难在不了解更多关于您想要丢弃的哪些“重复项”的情况下为您提供解决方案:您是否只想要一个可能的英文名称对于每个主题,或一个可能的出生日期(即使您的数据中可能有多个)?

    但是,这里有一些提示可以更轻松地处理/处理此类结果:

    首先,您可以选择在您的?subjectID 变量上使用ORDER BY 子句。这仍然会为您提供几行具有相同 ?subjectID 值的行,但它们都会按顺序排列,因此您可以更有效地处理结果。

    另一种解决方案是将您的查询一分为二:执行第一个查询,仅选择所有唯一主题(可能还有您事先知道它们将是唯一的所有其他值)主题),然后遍历结果并执行单独的查询以获取您感兴趣的其他值,对于每个单独的 subjectID 值。这个解决方案可能听起来像是异端(尤其是如果您有 SQL 背景),但实际上它可能比尝试在一个巨大的查询中完成所有事情更快、更容易。

    另一个解决方案是 RobV 建议的:在特定变量上使用 SAMPLE 聚合来仅选择一个(随机)唯一值。一种变体是使用GROUP_CONCAT 聚合,它通过将所有可能的值连接到单个字符串中来创建单个值。

    【讨论】:

    • 哇,谢谢,这非常有帮助。看了你的回复,我学到了很多。在等待的过程中,我确实进行了一些重构,并将查询一分为二。这违背了我的效率意识,但它是一个干净简单的解决方案。我从来没有在 SQL 中使用过 'GROUP_CONCAT',但基本上这确实解决了我关于如何处理平面图结构的问题。我的下一个问题,已经抢先! (与 RobV 一样,当我获得更多声誉时,请投票支持)
    猜你喜欢
    • 2016-11-10
    • 1970-01-01
    • 2019-05-03
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多