【问题标题】:Simplify SPARQL query简化 SPARQL 查询
【发布时间】:2015-04-06 22:43:35
【问题描述】:

我正在尝试使用 SPARQL 查询对 DBPedia 进行相当复杂的调用。我想获取有关城市的一些信息(区、联邦州/»Bundesland«、邮政编码、坐标和地理相关城市)。

Try online!

SELECT * WHERE {
  #input
  ?x rdfs:label "Bentzin"@de.

  #district
  OPTIONAL {
    ?x dbpedia-owl:district ?district
    # ?x dbpprop:landkreis ?district
    { SELECT * WHERE {
       ?district rdfs:label ?districtName
       FILTER(lang(?districtName) = "de")

       ?district dbpprop:capital ?districtCapital
       { SELECT * WHERE {
         ?districtCapital rdfs:label ?districtCapitalName
         FILTER(lang(?districtCapitalName) = "de")
       }}
    }}
  }

  #federal state
  OPTIONAL {
    # ?x dbpprop:bundesland ?land
    ?x dbpedia-owl:federalState ?land
    { SELECT * WHERE {
        ?land rdfs:label ?landName
        FILTER(lang(?landName) = "de")
    }}
  }

  #postal codes
  ?x dbpedia-owl:postalCode ?zip.

  #coordinates
  ?x geo:lat ?lat.
  ?x geo:long ?long

  #cities in the south
  OPTIONAL {
    ?x dbpprop:south ?south
    {SELECT * WHERE {
      ?south rdfs:label ?southName
      FILTER(lang(?southName) = "de")
    }}
  }

  #cities in the north
  OPTIONAL {
    ?x dbpprop:north ?north
    { SELECT * WHERE {
       ?north rdfs:label ?northName
       FILTER(lang(?northName) = "de")
    }}
  }

  #cities in the west
  ...

}

这在某些情况下有效,但是存在一些主要问题。

  1. 有几个不同的属性可能包含联邦州或地区的值。有时是dbpprop:landkreis(德语区的意思,在其他情况下是dbpedia-owl:district。如果只设置了一个,是否可以将这两者结合起来?

  2. 此外,我想念出北部、西北部……的城市名称。有时,dbpprop:north等会引用这些城市。每个方向的基本查询都是一样的:

    OPTIONAL {
      ?x dbpprop:north ?north
      { SELECT * WHERE {
        ?north rdfs:label ?northName
        FILTER(lang(?northName) = "de")
      }}
    }
    

    我真的不想每个方向都重复八次,有什么办法可以简化吗?

  3. 有时,还会引用多个其他城市 (example)。在这些情况下,会返回多个数据集。是否有可能在单个数据集中获取这些城市的名称列表?

    +---+---+---------------------------------------------------------------+
    | x | … |                            southName                          |
    +---+---+---------------------------------------------------------------+
    | … | … | "Darmstadt"@de, "Stuttgart"@de, "Karlsruhe"@de, "Mannheim"@de |
    +---+---+---------------------------------------------------------------+
    

非常感谢您的反馈和想法!

直到

【问题讨论】:

    标签: sparql dbpedia


    【解决方案1】:

    有几个不同的属性可能包含联邦州或地区的值。有时是 dbpprop:landkreis( 德语区的单词,在其他情况下是 dbpedia-owl:district。是 在只有其中之一的情况下,可以将这两者结合起来 设置好了吗?

    SPARQL 属性路径非常适合这一点。你可以说

    ?subject dbprop:landkreis|dbpedia-owl:district ?district
    

    如果有更多属性,您可能更喜欢具有值的版本:

    values ?districtProperty { dbprop:landkreis dbpedia-owl:district }
    ?subject ?districtProperty ?district
    

    还有,我想念出北方城市的名字, 西北, …。有时,这些城市在 dbpprop:north 中被引用 等等。每个方向的基本查询都是一样的:

    OPTIONAL {
      ?x dbpprop:north ?north
      { SELECT * WHERE {
        ?north rdfs:label ?northName
        FILTER(lang(?northName) = "de")
      }}
    }
    

    再次强调,价值观可以起到帮助作用。另外,不要使用 lang(…) = … 来过滤语言,使用 langMatches:

    optional {
      values ?directionProp { dbpprop:north
                              #-- ...
                              dbpprop:south }
      ?subject ?directionProp ?direction 
      optional { 
        ?direction rdfs:label ?directionLabel
        filter langMatches(lang(?directionLabel),"de")
      }
    }
    

    有时,还会引用多个其他城市(示例)。在 在这些情况下,会返回多个数据集。有没有 可以在一个单一的情况下获得这些城市的名称列表 数据集?

    +---+---+---------------------------------------------------------------+
    | x | … |                            southName                          |
    +---+---+---------------------------------------------------------------+
    | … | … | "Darmstadt"@de, "Stuttgart"@de, "Karlsruhe"@de, "Mannheim"@de |
    +---+---+---------------------------------------------------------------+
    

    这就是 group by 和 group_concat 的用途。见Aggregating results from SPARQL query。我实际上并没有在您提供的查询中看到这些结果,所以我没有很好的数据来测试结果。

    您似乎还做了很多不必要的子选择。您可以在图形模式中添加额外的三元组;您不需要嵌套查询来获取更多信息。

    考虑到这些因素,您的查询变为:

    select * where {
      ?x rdfs:label "Bentzin"@de ;
         dbpedia-owl:postalCode ?zip ;
         geo:lat ?lat ;
         geo:long ?long
    
      #-- district
      optional {
        ?x dbpedia-owl:district|dbpprop:landkreis ?district .
        ?district rdfs:label ?districtName
        filter langMatches(lang(?districtName),"de")
        optional {
          ?district dbpprop:capital ?districtCapital .
          ?districtCapital rdfs:label ?districtCapitalName
          filter langMatches(lang(?districtCapitalName),"de")
        }
      }
    
      #federal state
      optional  {
        ?x dbpprop:bundesland|dbpedia-owl:federalState ?land .
        ?land rdfs:label ?landName
        filter langMatches(lang(?landName),"de")
      }
    
      values ?directionProp { dbpprop:south dbpprop:north }
      optional {
        ?x ?directionProp ?directionPlace .
        ?directionPlace rdfs:label ?directionName 
        filter langMatches(lang(?directionName),"de")
      }
    }
    

    SPARQL results

    现在,如果您只是在寻找这些东西的名称,而没有关联的 URI,您实际上可以使用属性路径来缩短许多检索标签的结果。例如:

    select * where {
      ?x rdfs:label "Bentzin"@de ;
         dbpedia-owl:postalCode ?zip ;
         geo:lat ?lat ;
         geo:long ?long
    
      #-- district
      optional {
        ?x (dbpedia-owl:district|dbpprop:landkreis)/rdfs:label ?districtName
        filter langMatches(lang(?districtName),"de")
        optional {
          ?district dbpprop:capital/rdfs:label ?districtCapitalName
          filter langMatches(lang(?districtCapitalName),"de")
        }
      }
    
      #-- federal state
      optional  {
        ?x (dbpprop:bundesland|dbpedia-owl:federalState)/rdfs:label ?landName
        filter langMatches(lang(?landName),"de")
      }
    
      optional {
        values ?directionProp { dbpprop:south dbpprop:north }
        ?x ?directionProp ?directionPlace .
        ?directionPlace rdfs:label ?directionName
        filter langMatches(lang(?directionName),"de")
      }
    }
    

    SPARQL results

    【讨论】:

    • 这一切都很好!非常感谢。我正在使用(group_concat(?directionPlaceName; separator=",") as ?directionPlaceNames) 获取北部、南部等地的列表(see an example)。但是,这不会获得该地点的方向。 (在我的情况下这没问题。不过,我对一个解决方案感兴趣,该解决方案会为每个方向生成几列,每列都包含该特定方向的地点列表。不幸的是,我对这个主题完全陌生并且有还没有想出如何组合group_by 和group_concat。
    • @Till 您可以在 group_concat 中使用任意表达式。为什么不类似:group_concat(concat(str(?directionProp),":",?directionPlaceName);separator="; ") 得到类似 north:Place1; 的东西北:Place2;西:Place3?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多