假设这里的运行时上下文是Apache jena 3.4和ARQ查询引擎。考虑以下三元组:
:lib1 :makes "Butter"
:lib2 :makes "Bread"
可以通过各种方式直接询问:makes
和lib1
的lib2
属性,并返回一个文字字符串。太好了。但是,我希望将一组其他属性外部管理为散列映射,例如(这不是合法的RDF):
:lib1 :attrs {a:1, b:"hello", c:false}
这是因为我想将attrs分组在支持jena运行时的persistor中,而不是爆炸到这个:
:lib1 :attrs_a 1
:lib1 :attrs_b "hello"
:lib1 :attrs_c false
要么:
:lib1 :attrs::a 1
:lib1 :attrs::b "hello"
:lib1 :attrs::c false
我当然可以对来自缓冲器的数据进行一些额外的操作。让人想到的是subProperty
:
:attrs rdf:type rdf:Property
:a rdfs:subPropertyOf :attrs
:b rdfs:subPropertyOf :attrs
:c rdfs:subPropertyOf :attrs
然后
?resolveSubject ?p ?resolveObject .
?p rdfs:subPropertyOf+ :attrs
可用于动态获取所有subProperties。这有效,虽然在查询中也返回“父”属性attrs
,这有点令人恼火;我希望看到没有FILTER或其他类似的东西。
问题:在处理这种分组的动态数据时是否还有其他最佳实践/实用技巧和窍门?或者它很快归结为如何将它们变成子属性?
像{a:1, b:"hello", c:false}
这样的地图不是一个特别复杂的结构,它很容易在RDF中表示。它是一个具有三个条目的对象,每个条目将一个键与一个值相关联。所以,要近似
:lib1 :attrs {a:1, b:"hello", c:false}
你可以简单地做:
:lib1 :attrs [ :hasEntry [ :key "a"; :value 1 ] ,
[ :key "b"; :value "hello" ] ,
[ :key "c"; :value false ] ] .
当然,它看起来有点冗长,但你已经捕获了三元组的整个结构特别复杂,特别是如果你以编程方式发射它们。
这些也允许使用SPARQL进行相当简单的查询。例如,要询问库及其“c”属性,我们可以使用如下查询:
select ?lib ?value {
?lib :attrs/:hasEntry [ :key "c"; :value ?value ]
}