2

Virtuosoを使用してグラフ内の2つのノード間の距離を見つけるにはどうすればよいですか?推移性のドキュメントを読みましたが、1つの述語に制限されています。例:

SELECT ?link ?g ?step ?path
WHERE
{
  {
    SELECT ?s ?o ?g
    WHERE
      {
        graph ?g {?s foaf:knows ?o }
      }
  } OPTION (TRANSITIVE, t_distinct, t_in(?s), t_out(?o), t_no_cycles, T_shortest_only,
  t_step (?s) as ?link, t_step ('path_id') as ?path, t_step ('step_no') as ?step, t_direction 3) .
  FILTER (?s= <http://www.w3.org/People/Berners-Lee/card#i>
  && ?o = <http://www.advogato.org/person/mparaz/foaf.rdf#me>)
}
LIMIT 20

トラバースのみfoaf:knowsで、述語タイプはありません。これを「どの述語でも」に拡張するにはどうすればよいですか?実際のパスは必要ありません。true/false(ASKクエリ)だけが必要です。foaf:knowsを?pに変更するのはやり過ぎのようです。

私は現在、2つのノードが特定の距離内に接続されているかどうかを調べるために、一連の再帰ASKを実行していますが、それは効率的ではないようです。

4

2 に答える 2

4

?pクエリの代わりにを使用foaf:knowsして、ノード間にパスがあるかどうかを判断できるはずです。例えば:

SELECT ?link ?g ?step ?path
   WHERE
   {
     {
       SELECT ?s ?o ?g
       WHERE
         {
           graph ?g {?s ?p ?o }
         }
     } OPTION (TRANSITIVE, t_distinct, t_in(?s), t_out(?o), t_no_cycles, T_shortest_only,
     t_step (?s) as ?link, t_step ('path_id') as ?path, t_step ('step_no') as ?step, t_direction 3) .
     FILTER (?s= <http://www.w3.org/People/Berners-Lee/card#i>
     && ?o = <http://www.advogato.org/person/mparaz/foaf.rdf#me>)
   }
   LIMIT 20
于 2010-10-18T11:28:57.957 に答える
1

関心のあるノード間に最大で1つのパスがある場合に機能するアプローチは、次のとおりです。このようなデータがある場合(リソースを接続するさまざまなプロパティがあることに注意してください)。

@prefix : <https://stackoverflow.com/q/3914522/1281433/>

:a :p :b .
:b :q :c .
:c :r :d .

次に、次のようなクエリにより、ノードの各ペア間の距離が検出されます。プロパティパス(:|!:)は、(つまり、何か):以外のプロパティで構成されます。:したがって(:|!:)*、任意のプロパティの発生は0回以上です。ワイルドカードパスです。(ここで使用される手法については、SPARQLのRDFコレクション内の要素の位置を取得することは可能ですか?で詳しく説明されています。)

prefix : <https://stackoverflow.com/q/3914522/1281433/>

select ?begin ?end (count(?mid)-1 as ?distance) where {
 ?begin (:|!:)* ?mid .
 ?mid (:|!:)* ?end .
}
group by ?begin ?end
order by ?begin ?end ?distance
--------------------------
| begin | end | distance |
==========================
| :a    | :a  | 0        |
| :a    | :b  | 1        |
| :a    | :c  | 2        |
| :a    | :d  | 3        |
| :b    | :b  | 0        |
| :b    | :c  | 1        |
| :b    | :d  | 2        |
| :c    | :c  | 0        |
| :c    | :d  | 1        |
| :d    | :d  | 0        |
--------------------------

2つのノード間に特定の長さより短いパスがあるかどうかを確認するaskには、の代わりにクエリを使用し、とselectの値を修正し、の値をにバインドするのではなく制限します。たとえば、からの長さが3未満のパスはありますか??begin?endcount(?mid)-1?distance:a:d

prefix : <https://stackoverflow.com/q/3914522/1281433/>

ask {
 values (?begin ?end) { (:a :d) }
 ?begin (:|!:)* ?mid .
 ?mid (:|!:)* ?end .
}
group by ?begin ?end
having ( (count(?mid)-1 < 3 ) )
Ask => No

一方、から:aへのパス:cは長さが5未満です。

prefix : <https://stackoverflow.com/q/3914522/1281433/>

ask {
 values (?begin ?end) { (:a :c) }
 ?begin (:|!:)* ?mid .
 ?mid (:|!:)* ?end .
}
group by ?begin ?end
having ( (count(?mid)-1 < 5 ) )
Ask => Yes
于 2014-03-06T17:23:26.283 に答える