首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >昂贵的SPARQL操作,比较指南

昂贵的SPARQL操作,比较指南
EN

Stack Overflow用户
提问于 2014-08-06 13:43:40
回答 1查看 352关注 0票数 0

在运行SPARQL查询和编写清理结果的代码之间存在权衡。

复杂查询: Pros:获得干净/高效的结果,清除Cons:超时错误的代码较少,处理时间较长。

我知道不能泛化它,但是想比较一下组合子查询(UNION,.)、过滤器和集合,看看哪个操作在超时的情况下是更昂贵的操作。

例如,我正在从日语SPARQL端点运行这个查询(我删除了其中的一些部分)。

代码语言:javascript
运行
复制
SELECT ?film ?dblink ?filmType (group_concat(?actors ; separator = "|") AS ?actorset) (group_concat(?country ; separator = "|") AS ?countryset) (group_concat(?releaseDate ; separator = "|") AS ?releasedateset) (group_concat(?language ; separator = "|") AS ?languageset) (group_concat(?genre ; separator = "|") AS ?genreset) ?numberOfEpisodes  ?numberOfSeasons
WHERE {
     {?film a dbpedia-owl:Film } UNION {?film a dbpedia-owl:TelevisionShow } UNION {?film a dbpedia-owl:Cartoon } UNION {?film a dbpedia-owl:TelevisionSeason } .
     {?film a ?filmType  } .Filter(regex(?filmType,"(?:TelevisionSeason|Cartoon|Film|TelevisionShow)")) .
     OPTIONAL { {?film dbpedia-owl:starring ?actors} UNION {?film dbpprop:starring ?actors}  }. OPTIONAL { ?film dbpedia-owl:country ?country  }.  OPTIONAL { {?film dbpprop:genre ?genre} UNION  { ?film dbpedia-owl:genre ?genre  } }. OPTIONAL { {?film dbpprop:language ?language} UNION {?film dbpedia-owl:language ?language}  }. OPTIONAL { ?film dbpedia-owl:wikiPageID ?wikiPageID   } .
     OPTIONAL {?film owl:sameAs ?dblink . Filter (strstarts( str(?dblink), 'http://dbpedia.org/resource/'))}
 } LIMIT 5

它超时了。在后面的代码中,有什么更有效(避免超时)来删除和处理结果?

1-聚集 (group_concat)

2-过滤器:在我的代码中处理它

3-子查询:删除一些子查询(可选vs Union)并在另一个查询中执行它们

EN

回答 1

Stack Overflow用户

发布于 2014-08-06 15:06:45

优化问题很难解决,特别是当端点可以施加不同的限制时。尽管如此,至少有一些东西可以大大简化这个查询。

寻找某些类别的个人

代码语言:javascript
运行
复制
{?film a dbpedia-owl:Film } UNION {?film a dbpedia-owl:TelevisionShow } UNION {?film a dbpedia-owl:Cartoon } UNION {?film a dbpedia-owl:TelevisionSeason } .

真正应该是:

代码语言:javascript
运行
复制
values ?filmType { dbpedia-owl:Film
                   dbpedia-owl:Television
                   dbpedia-owl:Cartoon
                   dbpedia-owl:TelevisionSeason }
?film a ?filmType

它将处理所有固定类型。下一部分

代码语言:javascript
运行
复制
filter(regex(?filmType,"(?:TelevisionSeason|Cartoon|Film|TelevisionShow)"))

似乎是为了找到包含这些字符串之一的任何类型。这可能需要迭代所有的个体,以及它们的所有类型,然后对它们运行一个正则表达式。呃。更好的方法是找到具有与这些内容相匹配的名称的本体类,然后检索这些类的个人。

(请注意,在这里和上面,卡通可能指的是非电影的东西,例如报纸上的政治漫画。)

尽管如此,更好的解决方案可能是浏览类层次结构,并查看是否有您感兴趣的事物的公共超类。如果某物是子类的成员,那么它也是超类的成员,所以您可以通过这种方式节省一些查询。

寻找可选属性

代码语言:javascript
运行
复制
OPTIONAL { {?film dbpedia-owl:starring ?actors} UNION
           {?film dbpprop:starring ?actors}           } .
OPTIONAL { ?film dbpedia-owl:country ?country  } . 
OPTIONAL { {?film dbpprop:genre ?genre } UNION
           {?film dbpedia-owl:genre ?genre  } }.
OPTIONAL { {?film dbpprop:language ?language} UNION
           {?film dbpedia-owl:language ?language}  }.
OPTIONAL { ?film dbpedia-owl:wikiPageID ?wikiPageID   } .

要清理这些东西,你没什么可做的,只是:

  1. dbpedia-owl:properties拥有比dbpprop: properties更干净的数据,所以只要跳过dbpprop: properties就可以得到更好的结果。
  2. 也就是说,如果您确实希望获得基于属性以外的值,只需在属性路径中使用交替结构即可。例如,第一个可选块变成: 可选{{?电影dbpedia-owl:主演:dbpprop:主演?演员} 这就消除了联合,并使您的查询更加简单。

匹配资源以给定的命名空间开始。

代码语言:javascript
运行
复制
OPTIONAL { ?film owl:sameAs ?dblink .
           Filter (strstarts( str(?dblink), 'http://dbpedia.org/resource/'))}

这还不错,尽管owl:sameAs是传递性和自反性的,所以您可能应该让链接朝任何一个方向走。此外(这并不重要),通过使用str获取前缀,您可以使查询更易于维护。因此:

代码语言:javascript
运行
复制
prefix dbpedia: <http://dbpedia.org/resource/>

optional { ?film (owl:sameAs|^owl:sameAs)* ?dblink .
           filter (strstarts( str(?dblink), str(:dbpedia) ) }

聚合函数

代码语言:javascript
运行
复制
SELECT
  ?film ?dblink ?filmType
  (group_concat(?actors ; separator = "|") AS ?actorset)
  (group_concat(?country ; separator = "|") AS ?countryset)
  (group_concat(?releaseDate ; separator = "|") AS ?releasedateset)
  (group_concat(?language ; separator = "|") AS ?languageset)
  (group_concat(?genre ; separator = "|") AS ?genreset)
  ?numberOfEpisodes ?numberOfSeasons
WHERE { … }
LIMIT 5

您正在使用许多group_concat聚合。这本身可能不是什么问题,因为它只是遍历每个组并构建一个字符串。这是一个线性的结果(在小组之前),所以它不应该太昂贵。但是,同时选择组变量和非分组变量是不合法的。如果要选择5个没有聚合的变量,则需要显式地使用group:

代码语言:javascript
运行
复制
SELECT
  ?film ?dblink ?filmType
  (group_concat(?actors ; separator = "|") AS ?actorset)
  (group_concat(?country ; separator = "|") AS ?countryset)
  (group_concat(?releaseDate ; separator = "|") AS ?releasedateset)
  (group_concat(?language ; separator = "|") AS ?languageset)
  (group_concat(?genre ; separator = "|") AS ?genreset)
  ?numberOfEpisodes ?numberOfSeasons
WHERE {  }
GROUP BY ?film ?dblink ?filmType ?numberOfEpisodes ?numberOfSeasons
LIMIT 5

我知道Virtuoso可能接受没有显式组by的查询,但在SPARQL中它是必需的。事实上,我回答了answers.semanticweb.com最近的一个问题,变量已在范围内错误时使用。,它触及了这一点。在Spamql.org的验证器中检查查询是个好主意。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25161997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档