2013-08-02 35 views
5

Tôi mới sử dụng SPARQL và tôi đang cố tạo truy vấn đường dẫn thuộc tính sẽ nhổ ra từng bước trung gian dọc theo đường dẫn. Cho đến nay tôi có điều này:Tìm tất cả các bước trong đường dẫn thuộc tính

select ?object 
where { 
    <subjectURI> <isRelatedTo>+ ?object . 
} 

này mang lại cho tôi một danh sách tất cả các mối quan hệ đến chủ đề của tôi URI suốt con đường, bất kể có bao xa mối quan hệ (chính xác cho tôi nếu tôi sai cho đến nay).

Nhưng, tôi muốn xem cách các mối quan hệ được tổ chức. Một cái gì đó như:

<subjectURI> <isRelatedTo> <object1> 
<object1> <isRelatedTo> <object2> 
<object2> <isRelatedTo> <object3> 

và vân vân ... Điều này có thể?

+0

Chỉ cần nhìn thấy thông báo cho điều này, xin lỗi! Tôi đã không thực hiện bất kỳ tiến bộ vượt ra ngoài những gì trong các ý kiến ​​dưới đây. Dự án hiện đang được giữ lại, nhưng tôi hy vọng sẽ sớm quay lại dự án! – bdkauff

Trả lời

2

Không, đây là giới hạn của việc thiết kế đường dẫn thuộc tính.

Đường dẫn có thể được sử dụng để thu gọn các mẫu truy vấn phức tạp hơn hoặc chúng có thể được sử dụng để kiểm tra các đường dẫn dài tùy ý như trong ví dụ của bạn.

Tài liệu cũ có thể được chuyển đổi thành biểu mẫu cung cấp cho bạn các bước trung gian, ví dụ:

SELECT * WHERE 
{ 
    ?s <http://predicate>/<http://predicate> ?o 
} 

có thể được chuyển đổi như sau:

SELECT * WHERE 
{ 
    ?s <http://predicate> ?intermediate . 
    ?intermediate <http://predicate> ?o . 
} 

Thật không may là cùng không thể được thực hiện cho con đường dài tùy ý. Tuy nhiên, nếu bạn biết giới hạn trên của đường dẫn là bạn có thể viết lại truy vấn của mình như vậy:

SELECT * 
WHERE 
{ 
    { 
    ?s <http://predicate> ?step1 . 
    ?step1 <http://predicate> ?o . 
    } 
    UNION 
    { 
    ?s <http://predicate> ?step1 . 
    ?step1 <http://predicate> ?step2 . 
    ?step2 <http://predicate> ?o . 
    } 
    # Add additional UNION for each length of path you want up to your upper bound 
} 

Mặc dù bạn có thể thấy ngay điều này làm cho mọi thứ rất dài dòng.

+0

Cảm ơn! Tôi nghĩ rằng tôi nhớ lại đọc về giới hạn này. Các giải pháp là tiết, nhưng có lẽ ít hơn so với cố gắng để tái tạo lại các bước nhảy sau truy vấn. – bdkauff

+1

@ user2350906 Mặc dù có một số hạn chế đối với những gì bạn có thể làm với đường dẫn thuộc tính, tôi nghĩ bạn có thể lấy thông tin mà bạn đang tìm kiếm từ truy vấn sử dụng đường dẫn thuộc tính và tôi đã mô tả nó trong [câu trả lời] (http://stackoverflow.com/a/18032019/1281433). –

4

Trong khi có some limitations trong đường dẫn thuộc tính nào có thể làm, tùy thuộc vào yêu cầu chính xác của bạn, bạn có thể có được những gì bạn cần tại đây. Xem xét dữ liệu này:

@prefix : <urn:ex:>. 

:a :relatedTo :b . 
:b :relatedTo :c . 
:c :relatedTo :d . 

:a :relatedTo :e . 
:e :relatedTo :f . 
:f :relatedTo :g . 

:h :relatedTo :i . 
:i :relatedTo :j . 
:j :relatedTo :k . 
:k :relatedTo :l . 

trong đó có ba :relatedTo con đường:

a --> b --> c --> d 
a --> e --> f --> g 
h --> i --> j --> k --> l 

Tôi nhận ra rằng trong trường hợp của bạn, bạn đã có một chủ đề cụ thể, nhưng chúng ta có thể khái quát một chút, và yêu cầu mỗi cạnh trong mỗi đường dẫn này với một truy vấn như thế này:

prefix : <urn:ex:> 
select * where { 
    # start a path 
    ?begin :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    # grab next edge 
    ?midI :relatedTo ?midJ . 

    # get to the end of the path. 
    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
order by ?start ?end 

$ arq --data data.n3 --query query.sparql 
----------------------------- 
| begin | midI | midJ | end | 
============================= 
| :a | :a | :b | :d | 
| :a | :b | :c | :d | 
| :a | :c | :d | :d | 
| :a | :a | :e | :g | 
| :a | :e | :f | :g | 
| :a | :f | :g | :g | 
| :h | :h | :i | :l | 
| :h | :i | :j | :l | 
| :h | :j | :k | :l | 
| :h | :k | :l | :l | 
----------------------------- 

hiển thị từng cạnh của mỗi đường dẫn :relatedTo.Bạn có thể làm cho sản lượng một chút đẹp hơn, quá:

prefix : <urn:ex:> 
select (concat(str(?begin),"--",str(?end)) as ?path) ?midI ?midJ where { 
    # start a path 
    ?begin :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    # grab next edge 
    ?midI :relatedTo ?midJ . 

    # get to the end of the path. 
    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
order by ?path 

$ arq --data data.n3 --query query.sparql 
-------------------------------------- 
| path     | midI | midJ | 
====================================== 
| "urn:ex:a--urn:ex:d" | :a | :b | 
| "urn:ex:a--urn:ex:d" | :b | :c | 
| "urn:ex:a--urn:ex:d" | :c | :d | 
| "urn:ex:a--urn:ex:g" | :a | :e | 
| "urn:ex:a--urn:ex:g" | :e | :f | 
| "urn:ex:a--urn:ex:g" | :f | :g | 
| "urn:ex:h--urn:ex:l" | :h | :i | 
| "urn:ex:h--urn:ex:l" | :i | :j | 
| "urn:ex:h--urn:ex:l" | :j | :k | 
| "urn:ex:h--urn:ex:l" | :k | :l | 
-------------------------------------- 

Cách tiếp cận này cùng sẽ cho phép bạn làm một số điều thú vị như tìm ra cách xa tách nút nào đó là:

prefix : <urn:ex:> 
select ?begin ?end (count(*) as ?length) where { 
    # start a path 
    ?begin :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    # grab next edge 
    ?midI :relatedTo ?midJ . 

    # get to the end of the path. 
    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
group by ?begin ?end 

------------------------ 
| begin | end | length | 
======================== 
| :a | :g | 3  | 
| :a | :d | 3  | 
| :h | :l | 4  | 
------------------------ 

Trong dữ liệu tôi đã cung cấp ở trên, các đường dẫn xảy ra theo thứ tự bảng chữ cái và do đó việc sắp xếp tạo ra các cạnh theo thứ tự đúng. Tuy nhiên, ngay cả khi các nút cạnh không có trong bảng chữ cái, chúng tôi vẫn có thể in chúng theo thứ tự bằng cách tính toán vị trí của chúng trong danh sách. Truy vấn này:

prefix : <urn:ex:> 
select ?begin ?midI ?midJ (count(?counter) as ?position) ?end where { 
    ?begin :relatedTo* ?counter . 
    ?counter :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    ?midI :relatedTo ?midJ . 

    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
group by ?begin ?end ?midI ?midJ 

---------------------------------- 
| begin | midI | midJ | .1 | end | 
================================== 
| :a | :a | :b | 1 | :d | 
| :a | :b | :c | 2 | :d | 
| :a | :c | :d | 3 | :d | 
| :a | :a | :e | 1 | :g | 
| :a | :e | :f | 2 | :g | 
| :a | :f | :g | 3 | :g | 
| :h | :h | :i | 1 | :l | 
| :h | :i | :j | 2 | :l | 
| :h | :j | :k | 3 | :l | 
| :h | :k | :l | 4 | :l | 
---------------------------------- 

Chúng tôi cần không cần thiết phải thấy mà đếm, nhưng bạn có thể, thay vì chọn vị trí, bạn có thể sử dụng nó như một điều kiện sắp xếp:

prefix : <urn:ex:> 
select ?begin ?midI ?midJ ?end 
where { 
    ?begin :relatedTo* ?counter . 
    ?counter :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    ?midI :relatedTo ?midJ . 

    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
group by ?begin ?end ?midI ?midJ 
order by ?begin ?end count(?counter) 

và được đảm bảo để có được các cạnh của bạn theo thứ tự.

+0

Cảm ơn bạn đã phản hồi. Những gì bạn đề xuất làm việc lên đến một điểm, nhưng khi tôi thêm nhiều hơn một vài bước, truy vấn phản hồi không có gì. Theo truy vấn này: 'chọn? X (COUNT (? Z) AS? LinkTổng số) trong đó { ? X: relatedTo +? Z. } nhóm theo? X ĐANG (COUNT (? X)> 1) ' Tôi nhận giá trị tối đa là 12. Không có nghĩa là con đường ngắn nhất dài nhất là 12 bước và do đó tôi có thể để thêm 12 bước trung gian (err, 10?) vào truy vấn của bạn và vẫn nhận được một trường hợp phù hợp? – bdkauff

+0

@ user2350906 Nếu không nhìn thấy dữ liệu của bạn, thật khó để biết truy vấn sẽ trả về những gì. Tuy nhiên, tôi nhận thấy rằng bạn đang sử dụng '+', mà tôi không sử dụng trong bất kỳ truy vấn nào của mình. '+' có nghĩa là một hoặc nhiều, trong khi '*' là 0 hoặc nhiều hơn. –

+0

@ user2350906 Bạn có thể giải thích thêm về điều này nữa không? Sự khác biệt giữa '+' là quan trọng, và nếu bạn đang nhóm theo '? X', thì mệnh đề' HAVING' đó là 'HAVING (COUNT (? Z)> 1)' chứ không phải 'HAVING COUNT (? X)> 1) '(nghĩa là, đếm'? Z', không phải '? Y')? –

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