通过遵循 SPARQL 中的路径构造一组不同的三元组

问题描述 投票:0回答:1

我正在尝试编写一个 SPARQL 查询,该查询将使用 Construct 从三元组中提取所有相关的三元组。本质上,三元组存储包含一堆被解析为三元组的 JSON-LD 文档,因此有一组可预测的动词和模式,我的目标是通过获取相关三元组来重建其中一个文档。这些文档是 JSON 对象,大约有 7 个嵌套对象深度,其结构通常是已知的,但任何叶对象可能具有我想要取回的未知属性。所以我可以采取的一种方法是:

CONSTRUCT WHERE
{
  # get top level object
  ?subject <:knownProperty1> ?v1 .
  ?subject <:knownProperty2> ?v2 .
  ?subject <:knownProperty3> ?v3 .

  # leaf subobjects should get all their fields included
  ?v1 ?v1_p ?v1_o .
  ?v2 ?v2_p ?v2_o .
  ?v3 ?v3_p ?v3_o .

  # v3 has these nested objects.
  ?v3 <:knownNest1> ?n1 .
  ?n1 ?n1_p ?n1_o .

  # n2 is the next level of nesting
  ?n1 <:knownNest2> ?n2 .
  ?n2 ?n2_p ?n2_o .

  #... and so on
}

由于重复,这会产生一组比实际文档大几个数量级的三元组——它是正确的,但它为这些值的每个可能的组合匹配创建了“一个图表”;特别是因为每个嵌套级别可能有多个(一组)子对象。它变得更加毛茸茸的,因为许多已知字段也是可选的。因此,例如,所有图表匹配都为每个变量分配一个具体值,包括

?subject <:knownProperty1> <:value1>
,提供该三元组的一份副本,导致它被包含 100-1000 次。在我用来迭代的简单测试用例中,输入中有 106 个三元组,并且完全指定允许的结构(如上所示)会导致包含 550 万个三元组的 CONSTRUCT 结果集,查询延迟(在 RAM 中)超过60 秒。

我可以编写复杂的查询,但我相信这是一种代码味道,因为基本问题并不那么复杂。所以我的问题是:

  1. 我的想法是错误的吗?事实上,在 sparql 中编写一个查询来检索特定路径下的所有三元组是否非常困难?
  2. 有没有一种方便的方法来使用 SELECT DISTINCT 子查询来缩短这个时间?我对此的所有尝试都相当于“选择此模式上的每个不同的综合匹配”,这并没有更好。当模式匹配组合时,我想要不同的三元组。

或有关尝试此操作的正确方法的任何其他建议。谢谢!

sparql rdf graph-databases json-ld triplestore
1个回答
0
投票

是否存在重复的三元组(而不是由不在数据图中的模式生成的意外三元组)将取决于三元组存储。这是返回一组(每个三元组出现一次)与大结果的可扩展性(保持三元组停止提供流结果)的权衡。

复杂的 CONSTRUCT 可以通过控制模式来做到这一点:

CONSTRUCT { ... }
WHERE {
   SELECT DISTINCT vars needed by template {
      ...
   }
}

这会失去使用 CONSTRUCT WHERE 的能力,因此模板会被编写两次。 CONSTRUCT WHERE 只是一种方便的简写形式。

完整的CONSTRUCT在图案部分可以有OPTIONAL

© www.soinside.com 2019 - 2024. All rights reserved.