“Graph”中的“identifier”是什么作用?

3

我尝试像这样查询数据库:

from rdflib import Graph, Literal, URIRef
from rdflib.namespace import RDF, SKOS
from rdflib.plugins.stores import sparqlstore


# define endpoint according to https://www.stardog.com/docs/
endpoint = 'http://path/to/query'  # http://<server>:<port>/{db}/query

# create store
store = sparqlstore.SPARQLUpdateStore()

# I only want to query
store.open(endpoint)
store.setCredentials('me', 'my_pw')

# What does this actually do? That runs through
default_graph = URIRef('some:stuff')
ng = Graph(store, identifier=default_graph)
# # If identifier is not defined, it crashes
# ng = Graph(store)

rq = """
SELECT ?foo ?bar 
WHERE {
  ?something a <http://path/to/data/.ttl#SomeValues>.
  ?something <http://path/to/data/.ttl#foo> ?foo.
  ?something <http://path/to/data/.ttl#bar> ?bar.                       
}
"""

query_res = ng.query(rq)
for s, l in query_res:
    print(s, l)

很抱歉,目前我没有得到任何结果:

<head><variable name="foo"></variable><variable name="bar"></variable></head><results></results></sparql>

我的问题是,Graph中的identifier是做什么的,即它是否重要以及如何定义。如果我不定义它,代码会崩溃并显示以下错误信息:

Response: b'{"message":"No separator character found in the URI: N53e412e0f3a74d6eab7ed6da163463bf"}'

如果我输入任何其他带有冒号或斜杠的内容,它都可以运行(但查询仍然无法返回任何内容)。有人能简要解释一下,在那里应该放什么,以及这可能是查询失败的原因吗(查询命令本身是正确的;当我从另一个工具中调用它时,它可以正常工作)?

我猜您可以尝试在Stardog中使用“tag:stardog:api:context:default”。 - Stanislav Kralin
@StanislavKralin:再次感谢,我会尝试的!有没有办法检查store和/或ng中的内容,即是否有一种方法可以检查与数据库的连接是否正常并浏览其内容?我想将其缩小到ì)连接失败或ii)查询失败。有什么想法吗? - Cleb
在Stardog中,tag:stardog:api:context:default是一个“未命名”的图的名称。尝试使用简单的查询获取此未命名图的内容,例如SELECT * { ?s ?p ?o } LIMIT 10。结果看起来像你的东西吗? - Stanislav Kralin
我认为连接是正常的,结果看起来像SPARQL XML结果 - Stanislav Kralin
1
@StanislavKralin:使用“tag:stardog:api:context:default”就可以解决问题了。请继续将其作为答案添加,我会点赞并接受(请还附加您的调试策略,这也可能有助于其他人,“SELECT * { ?s ?p ?o } LIMIT 10”)。虽然不是原始问题的一部分,但现在清理“foo”和“bar”的结果最简单的方法是什么(值出现在链接的末尾;我必须手动清理此链接还是有内置的东西?),所以例如s看起来像http://path/to/#foo_i,我只想对所有i都有foo_i。谢谢! - Cleb
显示剩余4条评论
1个回答

1
Graph 构造函数的 identifier 参数允许识别一个 RDFLib 图。如果值为 None,则使用 空白节点 作为标识符。
然而,如果 store 值是 SPARQLUpdateStore,那么 identifier 值也被用作 SPARQL 协议的 default-graph-uri,因此不能是一个空白节点。
因此,问题是:远程三元组存储中默认的“未命名”图的名称是什么?
来自 Stardog 文档

Naming

Stardog includes aliases for several commonly used sets of named graphs. These non-standard extensions are provided for convenience and can be used wherever named graph IRIs are expected. This includes SPARQL queries & updates, property graph operations and configuration values. Following is a list of special named graph IRIs.

          Named Graph IRI                             Refers to                
--------------------------------  ---------------------------------------------
tag:stardog:api:context:default   the default (no) context graph              
tag:stardog:api:context:all       all contexts, including the default graph    
tag:stardog:api:context:named     all named graphs, excluding the default graph

我找不到任何公共或私有的Stardog端点(似乎ABS的端点已经失效)。以DBpedia为例:

from rdflib import Graph, URIRef
from rdflib.plugins.stores import sparqlstore

store = sparqlstore.SPARQLUpdateStore()
store.open('http://dbpedia.org/sparql')

default_graph = URIRef('http://people.aifb.kit.edu/ath/#DBpedia_PageRank') 
ng = Graph(store, identifier=default_graph)

rq = """
    SELECT ?foo ?foobar {
      ?foo ?foobar ?bar                       
    } LIMIT 100
"""

query_res = ng.query(rq)
for s, l in query_res:
    print(s, l)

结果与预期相似。即使在您的代码中,未命名图的名称是唯一的问题,获得的SPARQL XML结果也是正确的。

P.S. 也许你可以尝试使用 而不是 来实现你的目的。


tag:stardog:api:context:default 确实可以达到目的。我并不局限于 rdflib,并且非常乐意使用 sparqlwrapper。对于您而言,将上述代码进行调整以利用它需要多少工作量?或者,您能否向我指出一个设置凭据的代码示例呢? - Cleb
1
适应这段代码似乎也可以正常工作。然后似乎甚至不需要默认的图定义,它也能正常工作。 - Cleb
是的,使用SPARQLWrapper更短。据我所知,RDFLib的“SPARQLUpdateStore”封装了SPARQLWrapper。 - Stanislav Kralin
那么,你在回答中提到的是sparqlwrapper吗?还是另一个不同的库?直接使用它会更好,还是使用SPARQLUpdateStore有优势? - Cleb
1
如果您不想存储三元组,请直接使用SPARQLWrapper。 - Stanislav Kralin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接