2014-11-02 18 views
9

SPARQL property path truy vấn có độ dài tùy ý yêu cầu sử dụng các thuộc tính cụ thể. Tôi muốn truy vấn và tìm bất kỳ đường dẫn nào bắt đầu từ một tài nguyên và kết thúc bằng một tài nguyên khác. Ví dụ:Truy vấn đường dẫn thuộc tính SPARQL với các thuộc tính tùy ý

SELECT ?p 
WHERE { :startNode ?p* :endNode } 

trong đó ?p* chỉ định đường dẫn. Có cách nào để làm điều này?

+0

tôi bằng cách nào đó nghi ngờ rằng có thể với SPARQL (những gì sẽ '? P' liên kết với? chuỗi SPARQL tạo nên đường dẫn đặc tính cụ thể?), và bạn có thể muốn xem những gì mà [RelFinder] (http://www.visualdataweb.org/relfinder.php) đã tìm ra (nhiều hơn hoặc ít hơn) các kết nối tùy ý giữa hai tài nguyên. –

+1

Bạn có thể sử dụng ký tự đại diện bằng cách thực hiện một cái gì đó như '(<> |! <>) *', Cho phép bạn tìm ra * liệu có một đường dẫn từ địa điểm này đến địa điểm khác không, nhưng bạn không thể sử dụng các biến trong đường dẫn đặc tính . –

Trả lời

12

Bạn nói đúng là bạn không thể sử dụng các biến trong biểu thức đường dẫn thuộc tính. Tuy nhiên, có một vài điều mà bạn có thể có thể giúp bạn.

Một đại diện để kiểm tra liệu một con đường tồn tại

Bạn có thể sử dụng một ký tự đại diện bằng cách lấy phân ly của nó và phủ định của nó, vì vậy bạn có thể thực hiện một truy vấn đơn giản để kiểm tra liệu có một con đường kết nối hai nguồn:

<source> (<>|!<>)* <target> 

Nếu bạn có một tiền tố : xác định, mà có thể còn ngắn hơn, vì : là một IRI hợp lệ:

<source> (:|!:)* <target> 

Nếu có một con đường (hoặc nhiều đường dẫn) giữa hai nút, bạn có thể chia nó lên bằng con đường tự đại diện tham gia của ?p, và do đó tất cả các ?p s mà là trên con đường:

<source> (:|!:)* ?x . 
?x ?p ?y . 
?y (:|!:)* <target> . 

Bạn có thể làm cho điều đó thậm chí ngắn hơn, tôi nghĩ rằng, bằng cách sử dụng các nút trống thay vì ?x?y:

<source> (:|!:)* [ ?p [ (:|!:)* <target> ] ] 

(đó thể không làm việc, ngươi gh. Tôi dường như nhớ lại ngữ pháp thực sự không cho phép đường dẫn thuộc tính ở một số nơi trong các nút trống. Tôi không chắc chắn.)

Đối với một con đường duy nhất, có được tài sản và vị trí, sau đó group_concat

Bây giờ, trong trường hợp đó chỉ có một con đường giữa hai nguồn lực, thậm chí bạn có thể nhận được các thuộc tính cùng mà đường dẫn, cùng với vị trí của họ. Bạn có thể đặt hàng bởi các vị trí đó, và sau đó sử dụng một nhóm bằng cách nối các thuộc tính theo thứ tự thành một chuỗi đơn. Điều này có lẽ là dễ nhất để xem với một ví dụ. Giả sử bạn đã có các dữ liệu sau đó có một con đường duy nhất :a-:d:

@prefix : <urn:ex:> . 

:a :p1 :b . 
:b :p2 :c . 
:c :p3 :d . 

Sau đó, bạn có thể sử dụng một truy vấn như thế này để có được mỗi tài sản trong đường dẫn và vị trí của nó. (Điều này chỉ hoạt động nếu có một con đường duy nhất, mặc dù. Xem câu trả lời của tôi để Is it possible to get the position of an element in an RDF Collection in SPARQL? cho một chút thêm về cách làm việc này.)

prefix : <urn:ex:> 

select ?p (count(?mid) as ?pos) where { 
    :a (:|!:)* ?mid . 
    ?mid (:|!:)* ?x . 
    ?x ?p ?y. 
    ?y (:|!:)* :d 
} 
group by ?x ?p ?y 
------------- 
| p | pos | 
============= 
| :p2 | 2 | 
| :p1 | 1 | 
| :p3 | 3 | 
------------- 

Bây giờ, nếu bạn đặt hàng những kết quả theo ?pos và quấn rằng truy vấn trong một truy vấn khác, sau đó bạn có thể sử dụng group_concat trên ?p để nhận được một chuỗi các thuộc tính theo thứ tự. (Thứ tự đang được bảo quản không được bảo đảm, nhưng đó là hành vi khá phổ biến.Xem câu trả lời của tôi để obtain the matrix in protege cho một ví dụ về cách kỹ thuật này hoạt động, và my answer to Ordering in GROUP_CONCAT in SPARQL 1.1 để thảo luận về lý do tại sao nó không được đảm bảo.)

prefix : <urn:ex:> 

select (group_concat(concat('<',str(?p),'>');separator=' ') as ?path) { 
    select ?p (count(?mid) as ?pos) where { 
    :a (:|!:)* ?mid . 
    ?mid (:|!:)* ?x . 
    ?x ?p ?y. 
    ?y (:|!:)* :d 
    } 
    group by ?x ?p ?y 
    order by ?pos 
} 
----------------------------------------- 
| path         | 
========================================= 
| "<urn:ex:p1> <urn:ex:p2> <urn:ex:p3>" | 
----------------------------------------- 
+0

Tại sao ngay cả bận tâm với URI trống '<>'? Làm bất kỳ combo động cơ ba tầng/SPARQL thực sự cho phép điều này? Fuseki thay thế các URI trống bằng URL cục bộ thành biểu đồ hiện tại. Dường như bạn có thể bỏ qua URI trống và chỉ chọn '(! <>) *' –

+0

@Blakeregalia có, rất khó có thể gây ra vấn đề, nhưng đôi khi người ta sử dụng uris theo những cách kỳ lạ. Sử dụng thay thế được tất cả mọi thứ, bằng cách sử dụng phủ định được tất cả mọi thứ ngoại trừ một. Nếu bạn chắc chắn rằng không được sử dụng, thì từ chối đơn giản là tốt. –

Các vấn đề liên quan