2016-04-04 15 views
2

の2人の最も近い隣人を探す私は各点の2人の最も近い隣人にポイント

データセット見つけたい:私はこのような何かをしようと

?POINT ?NEIGHBORS 
"p1" "p2; p3" 
"p2" "p1; p3" 
"p3" "p2; p4" 
"p4" "p2; p3" 

:p1 :has_position 1 . 
:p2 :has_position 2 . 
:p3 :has_position 3 . 
:p4 :has_position 4 . 

期待される結果を

SELECT ?POINT ?POS (group_concat(?idPointN;separator='; ')as ?NEIGHBORS) 
WHERE{ 
    ?idPoint :has_position ?POS . 
    ?idPointN :has_position ?POSN . FILTER (?idPoint != ?idPointN) 
} 
GROUP BY ?POINT ?POS 

これはポイントのすべての近傍を返します。私はgroup_concatの中にORDER BY(?POS-?POSN)limit 2のような何かをしたいのですが、どうすればよいかわかりません。

EDIT:

は、私はそれが最も近いことにより、各ポイントのすべてのネイバーの順序を私を与える

SELECT ?POINT ?NEIGHBOR 
WHERE{ 
    ?idPoint rdfs:label ?POINT . FILTER(?idN != ?idPoint) 
    ?idPoint :has_position ?POS . 


    ?idN rdfs:label ?NEIGHBOR . 
    ?idN :has_position ?POSN . 
} 
ORDER BY ?POINT abs(?POS-?POSN) 

このクエリを記述します。

どのように私は2つの最も近いことができますか?と同じ行に?

+0

このためには、おそらくオーダーと限度を持つ副選択が必要です。 SPARQLでは、項目ごとの上位n個を取得するのが難しくなりますが、この場合は可能です。 –

+0

私はまた、{ \t \tこの \t 'SELECT POINTをNEIGHBOR \tを試してみましたidPointのrdfs:????POINTにラベルを付けます。 FILTER(?idNEIGHBOR!=?idPoint) \t \t?idPoint:has_position?POS。 \t \t { \t \t \t SELECT NEIGHBOR \t \t \t { \t \t \t \t idNEIGHBORのrdfs:???NEIGHBORにラベルを付けます。 \t \t \t \t?idNEIGHBOR:has_position?POSNEIGHBOR。 \t \t \t} \t \t \t ORDER BY?POINTのABS(?POS-?POSNEIGHBOR) \t \t \t LIMIT 2 \t \t} \t \t} ' しかし、結果は空の –

+0

I'LLですその日の少し後にこのショットを撮りましたが、それまでの間、http://stackoverflow.com/questions/27061096/sparql-using-subquery-with-limitと他のものの一部を見てくださいリンク先の質問(コメントを参照) –

答えて

1

SPARQLでは何かのトップnを取得するクエリは本当に難しいですが、実際にはまだそれを行うには素晴らしい方法はありません。ほとんどの場合、奇妙なハックになる。最初に、プレフィックス宣言を持つデータ:

@prefix : <urn:ex:> 

:p1 :has_position 1 . 
:p2 :has_position 2 . 
:p3 :has_position 3 . 
:p4 :has_position 4 . 

次にクエリ。 選択行に長い文字列連結がありますが、それは質問に記載されているように接頭辞を取り除くだけです。この場合の「ハック」は、2つの最も近い点が、qおよびrの量が最小になることを認識しています。| p − q | + | p − r |となるので、その数量を計算して、qrの値を取ってそれを私たちに渡すことができます。また、あなたがQR上のいくつかの順序を課すことを確認する必要があります、または他の(あなたがQRを単に入れ替える可能性があるので)あなたは、重複結果が得られます。今

prefix : <urn:ex:> 

select ?p (concat(strafter(str(?q),str(:)),", ",strafter(str(?r),str(:))) as ?neighbors) { 
    ?p :has_position ?pos1 . 
    ?q :has_position ?pos2 . 
    ?r :has_position ?pos3 . 
    filter(?p != ?q && ?p != ?r) 
    filter(str(?q) < str(?r)) 

    filter not exists { 
    ?qq :has_position ?pos22 . 
    ?rr :has_position ?pos33 . 
    filter(?p != ?qq && ?p != ?rr) 
    filter(str(?qq) < str(?rr)) 
    filter((abs(?pos1 - ?pos22) + abs(?pos1 - ?pos33)) < 
      (abs(?pos1 - ?pos2) + abs(?pos1 - ?pos3))) 
    } 
} 
------------------- 
| p | neighbors | 
=================== 
| :p1 | "p2, p3" | 
| :p2 | "p1, p3" | 
| :p3 | "p2, p4" | 
| :p4 | "p2, p3" | 
------------------- 

、あなたはまた、各のpのための最小限の量を見つけ、サブクエリでこれを行うことができ、その後、外側のクエリでは、QRを見つけそれを生産値:

prefix : <urn:ex:> 

select ?p (concat(strafter(str(?q), str(:)), ", ", strafter(str(?r), str(:))) as ?neighbors) { 
    { select ?p (min(abs(?pos1 - ?pos2) + abs(?pos1 - ?pos3)) as ?d) { 
     ?p :has_position ?pos1 . 
     ?q :has_position ?pos2 . 
     ?r :has_position ?pos3 . 
     filter(?p != ?q && ?p != ?r) 
     filter(str(?q) < str(?r)) 
    } 
    group by ?p 
    } 

    ?p :has_position ?pos1 . 
    ?q :has_position ?pos2 . 
    ?r :has_position ?pos3 . 
    filter(?p != ?q && ?p != ?r) 
    filter(str(?q) < str(?r)) 
    filter(abs(?pos1 - ?pos2) + abs(?pos1 - ?pos3) = ?d) 
} 
------------------- 
| p | neighbors | 
=================== 
| :p1 | "p2, p3" | 
| :p2 | "p1, p3" | 
| :p3 | "p2, p4" | 
| :p4 | "p2, p3" | 
------------------- 
+0

ありがとうございました。 –