【问题标题】:SPARQL: find subjects with the same set of triples?SPARQL:找到具有相同三元组的主题?
【发布时间】:2020-10-08 20:38:46
【问题描述】:

我正在尝试识别具有完全相同“集合”三元组的主题。在此示例数据中,:Set2 应被标识为与 :Set1 的唯一完全匹配,而 :Set1:Set3 由于值 :VAL_E 而不是完全匹配。

@prefix :  <https://www.example.org/Eg#>.

:Set1 :hasValue  :VAL_A, :VAL_B, :VAL_C, :VAL_D .
:Set2 :hasValue  :VAL_A, :VAL_B, :VAL_C, :VAL_D .
:Set3 :hasValue  :VAL_A, :VAL_B, :VAL_C, :VAL_D, :VAL_E .
:Set4 :hasValue  :VAL_A, :VAL_B .
:Set5 :hasValue  :VAL_F, :VAL_G, :VAL_H, :VAL_I, :VAL_J .

我在 StackOverflow 上找到了示例 SPARQL,它可以识别在 :Set1 和其他集合之间匹配的单个三元组,甚至是 number of matches,但不知道如何识别整个三元组的精确匹配。我预计需要 FILTER NOT EXISTS!SAMETERM 的组合,但我无法正确获取语法。

更新: 我改编了来自@StanislavKralin 的 SPARQL,以找到与 :Set1 相同的其他 Set。它几乎可以工作。

SELECT DISTINCT  ?s2 {
  :Set1 ?p ?o .
  ?s2 ?p ?o .
  FILTER NOT EXISTS { :Set1 ?p1 ?o1 . FILTER NOT EXISTS { ?s2 ?p1 ?o1 } }
  FILTER NOT EXISTS { ?s2 ?p2 ?o2 . FILTER NOT EXISTS { :Set1 ?p2 ?o2 } } # omits match from :Set3 to :Set1
  FILTER (STR(:Set1) < STR(?s2))
}

但是,我的查询结果中包含 :Set4,这是不正确的。

:Set2
:Set4

我错过了什么?

[更新] 正如下面的 cmets 所述,Stanislav 在 Stardog 社区论坛上提供了进一步的解释和代码:https://community.stardog.com/t/unexpected-sparql-filter-results/2745/14,以及来自 Pavel Klinov 解释 Stardog 当前行为的其他信息。如您所见,已打开一张票以供解决。同时,Stanislav 提供的这段代码提供了正确的结果:

SELECT DISTINCT ?s1 ?s2 {
  ?s1 ?p ?o .   
  ?s2 ?p ?o .
  FILTER NOT EXISTS {
    ?s1 ?p ?o . 
    ?s2 ?p ?o . 
    ?s1 ?p1 ?o1 . 
    FILTER NOT EXISTS { ?s2 ?p1 ?o1 } }
  FILTER NOT EXISTS {
    ?s1 ?p ?o . 
    ?s2 ?p ?o .
    ?s2 ?p2 ?o2 . 
    FILTER NOT EXISTS { ?s1 ?p2 ?o2 } }
  FILTER (STR(?s1) < STR(?s2))
}

【问题讨论】:

    标签: sparql rdf stardog


    【解决方案1】:

    在 Apache Jena Fuseki 和 Ontotext GraphDB 中测试:

    SELECT DISTINCT ?s1 ?s2 {
      ?s1 ?p ?o .
      ?s2 ?p ?o .
      FILTER NOT EXISTS { ?s1 ?p1 ?o1 . FILTER NOT EXISTS { ?s2 ?p1 ?o1 } }
      FILTER NOT EXISTS { ?s2 ?p2 ?o2 . FILTER NOT EXISTS { ?s1 ?p2 ?o2 } }
      FILTER (STR(?s1) < STR(?s2))
    }
    

    说明

    S1S2 是分别以:s1:s2 为主题的三元组集合。
    S1 ≡ S2 是什么意思?这意味着S1 ⊆ S2S2 ⊆ S1
    S1 ⊆ S2 是什么意思?这意味着∀x(x ∈ S1 → x ∈ S2).
    不幸的是,在 SPARQL 中没有像 ('for all')这样的东西。
    但是,可以改写 ¬∃x¬(x ∈ S1 → x ∈ S2) 并使用 SPARQL 的 NOT EXISTS
    最后,x ∈ S1 可以翻译成:s1 ?p ?o

    另见this answer

    【讨论】:

    • 您的查询结果是什么样的?请参阅上面我编辑的问题以进行尝试适应。
    • @Tim,我的查询返回({?s1→:Set1, ?s2→:Set2})。您的查询为我返回 ({?s2→:Set2}),而不是 ({?s2→:Set2}, {?s2→:Set4})。您使用的是哪个三联商店?
    • 我正在使用 Stardog 7。我会将此示例数据发布到他们的支持论坛,并在收到反馈时在此处更新。感谢您提供此信息!
    • 好的。我希望,这是一个查询优化问题。然而,这个问题本身很微妙,参见例如researchgate.net/publication/322518229
    • 感谢您在此处和 Stardog 论坛上的详细说明。我使用您提供的示例代码更新了我的问题,以便人们可以直接在 SO 上看到它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 1970-01-01
    • 2020-12-16
    相关资源
    最近更新 更多