
RDFLib 默认将 JSON-LD 中的数组属性视为无序集合,导致重复数值被合并;若需严格保留原始顺序与重复项,必须显式声明 "@container": "@list",使 rdflib 将其解析为 RDF 列表(rdf:List),而非多个独立三元组。
rdflib 默认将 json-ld 中的数组属性视为无序集合,导致重复数值被合并;若需严格保留原始顺序与重复项,必须显式声明 `"@container": "@list"`,使 rdflib 将其解析为 rdf 列表(`rdf:list`),而非多个独立三元组。
在语义网标准中,RDF 本身不支持“重复断言”或“有序多值属性”——同一主语-谓语组合下,若宾语值相同,则无论声明多少次,逻辑上仅等价于一次。因此,当 rdflib 解析如下 JSON-LD 片段时:
{
"@id": "some-id",
"@type": "Row",
"my_field": [-0.0368623323738575, 0.06313438713550568, -0.05376605689525604, -0.0368623323738575, 0.06313438713550568, -0.05376605689525604]
}
默认行为是为每个唯一数值生成一个 my_field 三元组(共 3 条),自动去重并丢失顺序信息——这符合 RDF 模型规范,但违背了某些应用场景(如特征向量、时序信号、嵌入向量)对完整性与序列性的要求。
✅ 正确解决方案:使用 @container: @list 显式建模为 RDF 列表
需在 @context 中为 my_field 字段指定容器类型,强制 rdflib 构建 rdf:first/rdf:rest 链式结构,完整保留所有元素(含重复项)及其原始顺序:
from rdflib import Graph
import json
jsonld_data = {
"@context": {
"@vocab": "http://example.com/test/",
"@language": "en",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"my_field": { "@id": "http://example.com/test/my_field", "@container": "@list" }
},
"@id": "some-id",
"@type": "Row",
"attendance": 74439,
"average_cards_per_match_pre_match": 0,
"average_corners_per_match_pre_match": 0,
"average_goals_per_match_pre_match": 0,
"my_field": [
-0.0368623323738575,
0.06313438713550568,
-0.05376605689525604,
-0.0368623323738575,
0.06313438713550568,
-0.05376605689525604
]
}
g = Graph()
g.parse(
data=json.dumps(jsonld_data),
format="json-ld"
)
# 序列化为 Turtle 可清晰查看列表结构
print(g.serialize(format="turtle").decode())
输出将包含完整的 rdf:List 结构(节选):
<some-id><http:> _:b0 .
_:b0 a rdf:List ;
rdf:first -0.0368623323738575e0 ;
rdf:rest _:b1 .
_:b1 rdf:first 0.06313438713550568e0 ;
rdf:rest _:b2 .
_:b2 rdf:first -0.05376605689525604e0 ;
rdf:rest _:b3 .
# ...(后续节点延续,直至 rdf:rest rdf:nil)</http:></some-id>
⚠️ 注意事项:
-
@container: "@list"是 JSON-LD 1.1 标准特性,需确保rdflib-jsonld>=0.6.1(推荐rdflib[jsonld]>=6.3.2); - 不要混用
@set或省略@container——前者仍会去重,后者触发默认集合行为; - 若需在 SPARQL 查询中展开该列表,须使用
rdf:rest*/rdf:first路径或专用列表函数(如LIST扩展); - 对于高维向量等大批量数值,建议结合
xsd:double类型声明(如"@type": "@double")提升序列化精度与互操作性。
总结:RDF 的“无重复、无序”本质不可绕过,但通过 @list 容器可将数组语义精准映射为 RDF 列表,既符合标准,又满足工程中对数据保真度的核心诉求。











