【发布时间】:2019-07-14 01:44:07
【问题描述】:
我正在尝试使用 EBI-RDF sparql endpoint 提取每个给定 GO Id(一个节点)的所有父母,我基于 this two 类似的问题来制定查询,这里有两个示例说明问题:
示例 1 (Link to the structure):
biological_process (GO:0008150)
|__ metabolic process (GO:0008152)
|__ methylation (GO:0032259)
在本例中,使用以下查询:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX dbpedia2: <http://dbpedia.org/property/>
PREFIX dbpedia: <http://dbpedia.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
SELECT (count(?mid) as ?depth)
(group_concat(distinct ?midId ; separator = " / ") AS ?treePath)
FROM <http://rdf.ebi.ac.uk/dataset/go>
WHERE {
obo:GO_0032259 rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?class .
?mid <http://www.geneontology.org/formats/oboInOwl#id> ?midId.
}
GROUP BY ?treePath
ORDER BY ?depth
我没有问题地得到了预期的结果:
c | treePath
--|-------------------------------------
6 | GO:0008150 / GO:0008152 / GO:0032259
但是当该术语存在于多个分支中时(例如GO:0007267),如下例所示,以前的方法不起作用:
示例 2 (Link to the structure)
biological_process (GO:0008150)
|__ cellular_process (GO:0009987)
| |__ cell communication (GO:0007154)
| |__ cell-cell signaling (GO:0007267)
|
|__ signaling (GO:0023052)
|__ cell-cell signaling (GO:0007267)
结果:
c | treePath
--|---------------------------------------------------------------
15| GO:0007154 / GO:0007267 / GO:0008150 / GO:0009987 / GO:0023052
我想要得到的是以下内容:
GO:0008150 / GO:0009987 / GO:0007154 / GO:0007267
GO:0008150 / GO:0023052 / GO:0007267
我的理解是,在后台我计算每个级别的深度并使用它来构建路径,当我们有一个仅属于一个分支的元素时,这可以正常工作。
SELECT (count(?mid) as ?depth) ?midId
FROM <http://rdf.ebi.ac.uk/dataset/go>
WHERE {
obo:GO_0032259 rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?class .
?mid <http://www.geneontology.org/formats/oboInOwl#id> ?midId.
}
GROUP BY ?midId
ORDER BY ?depth
结果:
depth | midId
------|------------
1 | GO:0008150
2 | GO:0008152
3 | GO:0032259
在第二个例子中,事情被遗漏了,我不明白为什么,无论如何我确信问题的一部分是具有相同深度/级别的术语,但我不知道如何我解决了这个问题。
depth | midId
------|------------
2 | GO:0008150
2 | GO:0009987
2 | GO:0023052
3 | GO:0007154
6 | GO:0007267
【问题讨论】:
-
不可能使用 SPARQL。它不关心树中的分支,它只关心模式匹配。您无法在分支之间的查询中区分,因此您无法遍历每个 .请注意,这不是 SPARQL 的目的,它不是图遍历语言。 GraphQL、Gremlin 等对于这个用例来说会是更好的语言。
-
注意,我只是指使用单个 SPARQL 查询的解决方案。实际上,您可以在客户端使用迭代执行的多个查询来遍历树中的路径。
-
@AKSW 感谢您的快速回答,我确实(使用 Ontology Lookup Service API)创建了一个递归函数,该函数遍历树并获取所有父级,但执行和执行花费了很多时间恐怕我会像您建议的那样使用多个查询时遇到同样的问题(我正在迭代一个具有 +50k GO ID 的文件);我会看看 GraphQL 和 Gremlin。
-
由于您的问题是针对Virtuoso-powered EMBL-EBI endpoint 的,我建议您将其提交给OpenLink Community Forum,Virtuoso 的开发人员可以更快地提供帮助。 Virtuoso 不支持 GraphQL 或 Gremlin,但可能还有其他方法可以实现您的目标。
-
you cannot distinguish the paths from where the ancestor nodes have been found@AKSW 我完全同意你所说的。您对使用 GraphQL 的建议很有趣(请在下面查看我的回答)。
标签: tree sparql ontology virtuoso