【问题标题】:RDFlib Blank node update queryRDFlib 空白节点更新查询
【发布时间】:2021-01-30 20:06:35
【问题描述】:

我正在尝试使用 RDFlib 更新以空白节点为主题的三元组的对象。我首先在第一个函数中选择空白节点,然后将此空白节点插入到第二个函数的更新查询中,但是,这并没有为我提供所需的输出。我无法使用 add() 方法或 initBindings,因为我需要保存为用户执行的 SPARQL 查询。

样本数据

@prefix rr: <http://www.w3.org/ns/r2rml#> .
[ rr:objectMap [ rr:column "age" ;
                 rr:language "dhhdhd"] ].

代码

mapping_graph = Graph().parse("valid_mapping.ttl",format="ttl")

# find the blank node for the update query 
def find_om_IRI():
    query = """SELECT ?om
                WHERE {
                  ?om rr:language 'dhhdhd' .
                }
           """
    qres = mapping_graph.query(query)
    for row in qres:
        return row[0]
# insert blank node as subject to update query
def change_language_tag():
    om_IRI = find_om_IRI()
    update_query = """
        PREFIX rr: <http://www.w3.org/ns/r2rml#>
        DELETE DATA{
            _:%s  rr:language 'dhhdhd' .
        }
        """ % (om_IRI)
    processUpdate(mapping_graph, update_query)
    print(update_query)
    print(mapping_graph.serialize(format="ttl").decode("utf-8"))
    return update_query


change_language_tag()

然而,这会返回以下输出。保持图表不变。

@prefix rr: <http://www.w3.org/ns/r2rml#> .
[ rr:objectMap [ rr:column "age" ;
                 rr:language "dhhdhd"] ].

【问题讨论】:

  • 查看blank-nodes标签信息。
  • 为什么不合并两个查询?将SELECT 的内容放在WHERE 部分的查询中,例如DELETE {?om rr:language 'dhhdhd'} WHERE { ?om rr:language 'dhhdhd' }
  • 不幸的是,我无法合并查询,因为可能存在具有相同语言标签的其他对象映射....不过感谢您的建议。
  • 但是你怎么知道你用你的代码删除了哪一个?只是随机一个吗?如果是这样,您可以通过DELETE {?om rr:language 'dhhdhd'} WHERE { SELECT ?om WHERE {?om rr:language 'dhhdhd' } LIMIT 1} 只选择一个
  • 我已经找到了解决方案并相应地更新了问题。它确实是一个 hack,但是,它确实有效。 RDFlib 中的空白节点在加载到 Graph() 类时被赋予唯一值。这些在查询时保持持久性,可用于引用值。

标签: sparql rdf rdflib turtle-rdf blank-nodes


【解决方案1】:

如果您根据空白节点值进行过滤。这是我想出的最后一个查询。

            PREFIX rr: <http://www.w3.org/ns/r2rml#> 
            DELETE { ?om rr:language "dhhdhd" } 
            INSERT { ?om rr:language "en-fhfhfh" } 
            WHERE { 
            SELECT ?om
            WHERE {
                  ?om rr:language "dhhdhd" .
                  FILTER(str(?om) = "ub1bL24C24").
                }
            }

【讨论】:

  • 哦,现在我明白了。那么你应该在 SPARQL 中使用空白节点表示法而不是过滤器:_:ub1bL24C24 rr:language "dhhdhd" .
  • STR 未在空白节点上定义 BTW :)。 stackoverflow.com/a/55445337/7879193
  • 这确实是一个 hack,并且不太可能(没关系保证)与 RDFlib 以外的任何 SPARQL 处理器一起使用。此外,您的 FILTER 子句表明您已经知道相关空白节点的内部标识符——无论如何都会(暂时)呈现它非空白——因此您可以使用更简单的查询,PREFIX rr: &lt;http://www.w3.org/ns/r2rml#&gt; DELETE { _:ub1bL24C24 rr:language "dhhdhd" } INSERT { _:ub1bL24C24 rr:language "en-fhfhfh" }
  • 它适用于我正在使用的 RDFlib 处理器。 @TallTed 那是我尝试过的原始查询,但是它没有用。我已经联系了 Github 的合作者,希望能找到原因.....
  • 我注意到这个 hack 可能不适用于任何其他 SPARQL 处理器,因为否则这个解决方案可能会被其他人找到,并被认为是一个 SPARQL 解决方案——它不是;它是一个 RDFlib 解决方案。我建议在此处添加指向 github 问题/线程的链接,以便其他人以后可以跟进。
【解决方案2】:

确实,正如评论者@TallTed 所说“不能在单独的查询中直接引用空白节点”。您正在尝试对未明确定义的 BN 做一些事情,即保持其绝对身份,例如跨单独的查询。您应该采用相对标识(参考已标识、URI、节点来定位 BN)或单个 SPARQL 查询的方法。所以这个问题是 RDF/SPARQL 问题,而不是 RDFlib 问题。

您说:“我无法组合查询,因为可能存在具有相同语言标签的其他对象映射”。因此,如果由于缺乏明确性而无法确定地引用节点,则必须更改数据,但我怀疑您可以 - 请参阅最后的建议。

然后你说“我已经找到了解决方案并相应地更新了问题。它真的是一个黑客......”是的,不要这样做!您应该有一个不依赖于 RDFlib 某些怪癖的解决方案! RDF 和语义网一般都是关于通用定义和标准的数据和查询,所以不要依赖特定的工具包来解决这样的数据问题。仅将 RDFlib 用作实现,但应该可以用另一种语言复制。我个人首先将我所有的 RDFlib 三重添加/删除/选择代码建模为标准 SPARQL 查询,这样我的 RDFlib 代码就只是一个等效的标准函数。

在您自己的回答中,您说“如果您根据空白节点值进行过滤...”,也不要这样做!

我的建议是更改您的基础数据以包含事物的表示 - 命名节点等 - 您可以用来修复查询。如果您无法在不借助 hack 的情况下区分要更改的内容,那么您就有一个需要解决的数据建模问题。我确实认为您可以区分对象映射。

在您的数据中,您必须能够修复要更改语言的特定对象映射。每个列的对象映射是否唯一,并且该列是否由其 rr:column 值唯一标识?如果是这样:

SELECT ?lang
WHERE {
  ?om rr:column ?col .  ?om rr:language ?lang .
  FILTER (?col = "age")
}

这将为您提供“年龄”列的对象映射,因此,更改它:

DELETE {
  ?om rr:language ?lang .
}
INSERT {
  ?om rr:language "new-language" .
}
WHERE {
  ?om rr:column ?col .  ?om rr:language ?lang .

  FILTER (?col = "age")
}

【讨论】:

    猜你喜欢
    • 2016-06-09
    • 2017-10-11
    • 2017-04-12
    • 2017-10-22
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多