这个问题与rcreswick关于Serializing Jena OntModel Changes的问题有关。我在需要通过套接字保持同步的两台(或更多)机器上有 Jena 模型。我需要解决的主要问题是模型可能包含匿名节点(bnodes),它可以源自任何模型。
问题:我是在正确的轨道上,还是有更好、更强大的方法我没有考虑?
我可以想到 3 种方法来解决这个问题:
- 序列化完整模型:这对于同步小更新来说非常昂贵。此外,由于任何一台机器都可能发生变化,我不能只用机器 A 的序列化模型替换机器 B 的模型。我需要合并它们。
- 序列化部分模型:使用专用模型进行序列化,该模型仅包含需要通过套接字发送的更改。这种方法需要特殊的词汇表来表示从模型中删除的语句。据推测,当我将模型从机器 A 序列化到机器 B 时,匿名节点 ID 对于机器 A 将是唯一的,但可能与在机器 B 上创建的匿名节点的 ID 重叠。因此,我必须重命名匿名节点并保留映射从机器 A 的匿名 ID 到机器 B 的 ID,以便正确处理未来的更改。
- 序列化单个语句:这种方法不需要特殊的词汇,但可能不那么健壮。除了匿名节点之外,还有其他我还没有遇到的问题吗?
- Generate global unique bnode ids (NEW):我们可以通过在 ID 前加上唯一的机器 ID 来为匿名节点生成全局唯一的 ID。不幸的是,我还没有弄清楚如何告诉 Jena 使用我的 ID 生成器而不是它自己的。这将允许我们在不重新映射 bnode ID 的情况下序列化单个语句。
这里有一个例子可以让这个讨论更深入一点。假设我在机器 A 上有一个列表,表示为:
_:a rdf:first myns:tom
_:a rdf:rest rdf:nil
我将这个模型从机器 A 序列化到机器 B。现在,因为机器 B 可能已经有一个(不相关的)匿名节点,id 为“a”,我将 id 'a' 重新映射到新的 id 'b':
_:b rdf:first myns:tom
_:b rdf:rest rdf:nil
现在机器 A 上的列表发生了变化:
_:a rdf:first myns:tom
_:a rdf:rest _:b
_:b rdf:first myns:dick
_:b rdf:rest rdf:nil
由于机器 B 之前从未遇到过机器 A 的 id 'b',它添加了一个从机器 A 的 id 'b' 到新的 id 'c' 的新映射:
_:b rdf:first myns:tom
_:b rdf:rest _:c
_:c rdf:first myns:dick
_:c rdf:rest rdf:nil
如果有两台以上的机器,问题会更加复杂。例如,如果有第三台机器 C,它可能有自己的匿名节点“a”,它不同于机器 A 的匿名节点“a”。因此,机器 B 确实需要保存从其他机器的每个匿名节点 ID 到其本地 ID 的映射,而不仅仅是从一般的远程 ID 到本地 ID。在处理传入的更改时,必须考虑更改的来源以正确映射 ID。