使用SPARQL查找列表中元素的相对位置 [英] Finding the relative position of elements in a list using SPARQL

查看:0
本文介绍了使用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 :0
:c :y :1
:b :v :2
:b :z :2

到目前为止的代码... (在Find lists containing ALL values in a set?Is it possible to get the position of an element in an RDF Collection in SPARQL?的帮助下)

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

我一直试图通过按?s分组来获得最小的?dif(差异/距离),但因为我必须将此(类似于?dif=?Mindif)应用于前面的?s?O分组,所以我不知道如何在这两个分组之间来回切换。

感谢您能提供的任何帮助

推荐答案

配制解决方案所需的是另一个约书亚·泰勒的答案:thisthis

下面我使用的是Jena函数,但我希望意思清楚。

查询%1

PREFIX list: <http://jena.hpl.hp.com/ARQ/list#>
SELECT ?s ?el ?dif {
    ?s : ?el .
    :ls :list/list:index (?pos ?el) .
    :ls :list/list:index (?ref :x) .
    BIND (ABS(?pos -?ref) AS ?dif) 
    {
    SELECT ?s (MIN (?dif_) AS ?dif) WHERE {
        ?s : ?el_ .
        :ls :list/list:index (?pos_ ?el_) .
        :ls :list/list:index (?ref_ :x) .
        BIND (ABS(?pos_ - ?ref_) AS ?dif_)
        } GROUP by ?s
    }
}

查询%2

PREFIX list: <http://jena.apache.org/ARQ/list#>    
SELECT ?s ?el ?dif {
    ?s : ?el .
    :ls :list/list:index (?pos ?el) .
    :ls :list/list:index (?ref :x) .
    BIND (ABS(?pos -?ref) AS ?dif) 
    FILTER NOT EXISTS {
        ?s : ?el_ .
        :ls :list/list:index (?pos_ ?el_) .
        BIND (ABS(?pos_ - ?ref) AS ?dif_) .
        FILTER(?dif_ < ?dif)                                           
    }
}

更新

可以这样重写查询%1:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ?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} } 
  BIND (ABS(?pos - ?ref) AS ?dif) 
  {
  SELECT ?s (MIN(?dif_) AS ?diff) {
    ?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} } 
    BIND (ABS(?pos_ - ?ref_) AS ?dif_)
    } GROUP by ?s
  }
  FILTER (?dif = ?diff)
}

备注

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

这篇关于使用SPARQL查找列表中元素的相对位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆