使用SPARQL查找列表中元素的相对位置

使用SPARQL查找列表中元素的相对位置,sparql,Sparql,我试图根据主题在有序列表中的相对位置返回主题 一个主语可以与多个对象关联(通过一个谓词),并且所有对象都在一个有序列表中。给定这个列表中的一个参考对象,我想按对象与参考对象的相对距离的顺序返回对象 :a : :x :b : :v :b : :z :c : :v :c : :y :ls :list (:v :w :x :y :z) 将x作为列表中的起始对象,下面的代码返回 :a :x :0 :c :y :1 :b :v :2 :b :z :2 :c :v :2 与返回所有位置不同,

我试图根据主题在有序列表中的相对位置返回主题

一个主语可以与多个对象关联(通过一个谓词),并且所有对象都在一个有序列表中。给定这个列表中的一个参考对象,我想按对象与参考对象的相对距离的顺序返回对象

:a : :x     
:b : :v
:b : :z
:c : :v
:c : :y

:ls :list (:v :w :x :y :z)
将x作为列表中的起始对象,下面的代码返回

:a :x :0
:c :y :1
:b :v :2
:b :z :2
:c :v :2
与返回所有位置不同,我只希望返回与对象最小对象“距离”相关的对象(这可能意味着每个对象最多返回两个对象-列表上下)。所以我想回来

:a :x :0
:c :y :1
:b :v :2
:b :z :2
到目前为止的代码。。。 (在和的大量帮助下)

我一直试图通过s分组来获得最小的?dif(差异/距离),但因为我必须将它(类似于?dif=?minDif)应用到之前的?s?o分组中,我不知道如何在这两个分组之间来回移动


感谢您提供的任何帮助

合成解决方案所需的只是约书亚·泰勒的另一个答案:或

下面我使用的是Jena函数,但我希望这个想法很清楚

查询1

前缀列表:
选择?s?el?dif{
s:?埃尔。
:ls:list/list:index(?pos?el)。
:ls:list/list:index(?ref:x)。
绑定(ABS(?位置-?参考)为dif)
{
选择?s(最小值(?dif_)作为?dif),其中{
s:厄尔尼诺。
:ls:list/list:index(?pos_u?el_u)。
:ls:list/list:index(?ref_uux)。
绑定(ABS(?位置-?参考)为dif)
}分组
}
}
查询2

前缀列表:
选择?s?el?dif{
s:?埃尔。
:ls:list/list:index(?pos?el)。
:ls:list/list:index(?ref:x)。
绑定(ABS(?位置-?参考)为dif)
筛选器不存在{
s:厄尔尼诺。
:ls:list/list:index(?pos_u?el_u)。
将(ABS(?位置-?参考)绑定为dif。
过滤器(?dif<?dif)
}
}
更新

查询1可以这样重写:

前缀rdf:
选择?s?el?dif{
s:?el
{select(count(*)as?pos)?el{[]:list/rdf:rest*/rdf:rest*/rdf:first?el}group by?el}
{select(count(*)as?ref){[]:list/rdf:rest*/rdf:rest*/rdf:first:x}
绑定(ABS(?位置-?参考)为dif)
{
选择?s(最小(?dif_u2;)作为?diff){
s:?厄尔乌
{select(count(*)as?pos_}?el_{[]:list/rdf:rest*/rdf:rest*/rdf:first?el_}按?el_}分组
{select(count(*)as?ref.{[]:list/rdf:rest*/rdf:rest*/rdf:first:x}
绑定(ABS(?位置-?参考)为dif)
}分组
}
过滤器(?dif=?差异)
}
注释

  • 正如您所看到的,这不是SPARQL的设计目的。例如,Blazegraph支持Gremlin
  • 这可能不是RDF设计的目的。或者尝试其他建模方法:您真的需要RDF列表吗
  • 我还没有在Virtuoso中测试上述查询

您确定这是SPARQL的正确用例吗?听起来更像是像Cypher或Gremlin这样的图形遍历引擎在这里工作得更好。谢谢@AKSW的推荐。我想将列表提供的层次结构合并到我的SPARQL查询中,但如果我继续使用这种方法,我将研究图形遍历引擎。感谢@Stanislav Kralin,我刚刚使用了直接SPARQL(因此是详细的位置查询)。再次感谢@Stanislav Kralin。我只是想使用列表提供的层次结构来探索一些数据(同时更加熟悉SPARQL)。如果它看起来很有希望,并且我继续使用这种方法,我将检查Gremlin。另外,我刚刚在RDFLib中运行了这些查询,它们都工作得很好。
SELECT ?s ?p (abs(?refPos-?pos) as ?dif) 
WHERE {
      :ls :list/rdf:rest*/rdf:first ?o .
      ?s : ?o .
      {
      SELECT ?o (count(?mid) as ?pos) ?refPos 
      WHERE {
            [] :list/rdf:rest* ?mid . ?mid rdf:rest* ?node .
            ?node rdf:first ?o .
            {
            SELECT ?o (count(?mid2) as ?refPos)
            WHERE {
                  [] :list/rdf:rest* ?mid2 . ?mid2 rdf:rest* ?node2 .
                  ?node2 rdf:first :x .
                  }
            }
            }
            GROUP BY ?o
      }
      }
      GROUP BY ?s ?o
      ORDER BY ?dif