2012-11-15 32 views
9

Sử dụng truy vấn cypher trên neo4j, theo đồ thị theo chu kỳ, theo chu kỳ, tôi cần truy vấn BFS và phân loại nút mục tiêu theo độ sâu.tính tổng chi phí đường dẫn trong cypher, lấy hướng liên quan đến tài khoản

Đối với bên trong sâu phân loại, một phong tục "tổng hàm chi phí con đường" nên được sử dụng, tính toán dựa trên

  • tất cả các mối quan hệ thuộc tính r.followrank giữa bắt đầu và nút cuối.
  • quan directionality (followrank nếu nó trỏ về phía nút kết thúc, hoặc 0 nếu không muốn nói)

Ở bất kỳ độ sâu tìm kiếm n, một nút kết nối với một nút xếp hạng cao ở mức n-m, m>0 nên được xếp hạng cao hơn một nút được kết nối với nút được xếp hạng thấp ở cấp độ n-m. Đảo ngược hướng nên kết quả trong một thứ hạng 0 (có nghĩa là, nút và subtree của nó vẫn là một phần của bảng xếp hạng).

Tôi đang sử dụng neo4j community-1.9.M01. Cách tiếp cận mà tôi đã thực hiện cho đến nay là trích xuất một mảng theo dõi cho đường đi ngắn nhất đến mỗi nút kết thúc

Tôi nghĩ tôi đã đưa ra ý tưởng đầu tiên tuyệt vời cho truy vấn này nhưng dường như nó bị hỏng điểm.

truy vấn của tôi là:

START strt=node(7) 
MATCH p=strt-[*1..]-tgt 
WHERE not(tgt=strt) 
RETURN ID(tgt), extract(r in rels(p): r.followrank*length(strt-[*0..]-()-[r]->())) as rank, extract(n in nodes(p): ID(n)); 

mà kết quả đầu ra

==> +-----------------------------------------------------------------+ 
==> | ID(tgt) | rank     | extract(n in nodes(p): ID(n)) | 
==> +-----------------------------------------------------------------+ 
==> | 14  | [1.0]     | [7,14]      | 
==> | 15  | [1.0,1.0]    | [7,14,15]      | 
==> | 11  | [1.0,1.0,1.0]   | [7,14,15,11]     | 
==> | 8  | [1.0,1.0,1.0,1.0,0.0] | [7,14,15,11,7,8]    | 
==> | 9  | [1.0,1.0,1.0,1.0,0.0] | [7,14,15,11,7,9]    | 
==> | 10  | [1.0,1.0,1.0,1.0,0.0] | [7,14,15,11,7,10]    | 
==> | 12  | [1.0,1.0,1.0,0.0]  | [7,14,15,11,12]    | 
==> | 8  | [0.0]     | [7,8]       | 
==> | 9  | [0.0]     | [7,9]       | 
==> | 10  | [0.0]     | [7,10]      | 
==> | 11  | [1.0]     | [7,11]      | 
==> | 15  | [1.0,1.0]    | [7,11,15]      | 
==> | 14  | [1.0,1.0,1.0]   | [7,11,15,14]     | 
==> | 8  | [1.0,1.0,1.0,1.0,0.0] | [7,11,15,14,7,8]    | 
==> | 9  | [1.0,1.0,1.0,1.0,0.0] | [7,11,15,14,7,9]    | 
==> | 10  | [1.0,1.0,1.0,1.0,0.0] | [7,11,15,14,7,10]    | 
==> | 12  | [1.0,0.0]    | [7,11,12]      | 
==> +-----------------------------------------------------------------+ 
==> 17 rows 
==> 38 ms 

Nó trông giống như những gì tôi cần, nhưng vấn đề là

  1. nút 8, 9, 10, 11 có cùng hướng quan hệ với 7! Kết quả truy vấn ngược ...*length(strt-[*0..]-()-[r]->())... trông thậm chí còn lạ hơn - xem các truy vấn ngay bên dưới.
  2. Tôi không biết làm thế nào để bình thường hóa các kết quả của biểu thức length() để 1.

Tính định hướng: truy vấn

START strt=node(7) 
MATCH strt<-[r]-m 
RETURN ID(m), r.followrank; 
==> +----------------------+ 
==> | ID(m) | r.followrank | 
==> +----------------------+ 
==> | 8  | 1   | 
==> | 9  | 1   | 
==> | 10 | 1   | 
==> | 11 | 1   | 
==> +----------------------+ 
==> 4 rows 
==> 0 ms 
START strt=node(7) 
MATCH strt-[r]->m 
RETURN ID(m), r.followrank; 
==> +----------------------+ 
==> | ID(m) | r.followrank | 
==> +----------------------+ 
==> | 14 | 1   | 
==> +----------------------+ 
==> 1 row 
==> 0 ms 

Inverse:

START strt=node(7) 
MATCH p=strt-[*1..]-tgt 
WHERE not(tgt=strt) 
RETURN ID(tgt), extract(rr in rels(p): rr.followrank*length(strt-[*0..]-()<-[rr]-())) as rank, extract(n in nodes(p): ID(n)); 
==> +-----------------------------------------------------------------+ 
==> | ID(tgt) | rank     | extract(n in nodes(p): ID(n)) | 
==> +-----------------------------------------------------------------+ 
==> | 14  | [1.0]     | [7,14]      | 
==> | 15  | [1.0,1.0]    | [7,14,15]      | 
==> | 11  | [1.0,1.0,1.0]   | [7,14,15,11]     | 
==> | 8  | [1.0,1.0,1.0,1.0,3.0] | [7,14,15,11,7,8]    | 
==> | 9  | [1.0,1.0,1.0,1.0,3.0] | [7,14,15,11,7,9]    | 
==> | 10  | [1.0,1.0,1.0,1.0,3.0] | [7,14,15,11,7,10]    | 
==> | 12  | [1.0,1.0,1.0,2.0]  | [7,14,15,11,12]    | 
==> | 8  | [3.0]     | [7,8]       | 
==> | 9  | [3.0]     | [7,9]       | 
==> | 10  | [3.0]     | [7,10]      | 
==> | 11  | [1.0]     | [7,11]      | 
==> | 15  | [1.0,1.0]    | [7,11,15]      | 
==> | 14  | [1.0,1.0,1.0]   | [7,11,15,14]     | 
==> | 8  | [1.0,1.0,1.0,1.0,3.0] | [7,11,15,14,7,8]    | 
==> | 9  | [1.0,1.0,1.0,1.0,3.0] | [7,11,15,14,7,9]    | 
==> | 10  | [1.0,1.0,1.0,1.0,3.0] | [7,11,15,14,7,10]    | 
==> | 12  | [1.0,2.0]    | [7,11,12]      | 
==> +-----------------------------------------------------------------+ 
==> 17 rows 
==> 30 ms 

Vì vậy, câu hỏi của tôi là:

  1. điều gì xảy ra với truy vấn này?
  2. có cách tiếp cận hoạt động không?

Để biết thêm chi tiết, tôi biết tập hợp tối thiểu (chiều dài (đường dẫn)) nhưng không hoạt động trong trường hợp này tôi đang cố trích thông tin về lần truy cập tốt nhất - thông tin bổ sung mà tôi trả về về cú đánh tốt nhất sẽ không phân biệt kết quả một lần nữa - Tôi nghĩ đó là giới hạn của cypher.

+0

để phần đầu của câu hỏi của bạn, kiểm tra này: http : //console.neo4j.org/r/gm59jt và http://console.neo4j.org/r/nvbdud. khi bạn chưa xác định hướng trong phần khớp, hơn thuật toán di chuyển đi tới một nút, hơn là quay lại nút khởi đầu và đơn giản hơn so với nút khác. cùng một số lượng cho các đường dẫn dài hơn, như đi từ nút bắt đầu đến nexth và nexth, gấp 2 lần trở lại và một lần nữa ở một nơi khác. điều này không chống lại bất kỳ lý thuyết đồ thị nào - nó thực sự là một hành vi đúng đắn. – ulkas

+0

thực sự và xin lỗi, nó có thể là đây là vấn đề ở đây thực sự. Nhưng tại sao con đường không phản ánh điều này? Ngay cả khi tôi trả về toàn bộ đường dẫn p thay vì chỉ các nút (p), thì không có dấu hiệu của định tuyến như vậy. Tôi sẽ mong đợi con đường để nói "x-> z-> x-> y" và chiều dài (p) = 3. Đây có phải là một lỗi neo4j? – bebbi

+0

có thể có nhiều triển khai neo4j hơn theo hướng mối quan hệ. ví dụ: khi tạo biểu đồ nhưng không đặt bất kỳ hướng nào cho các mối quan hệ của nó, neo4j tự thêm hướng dẫn. điều này là do một số lý do lịch sử, tôi đoán hiệu suất là tốt hơn khi tính toán với 2 loại rels (outgoing và ingoin) so với 3 (outgoing, ingoing, non-directed). do đó, tôi giả sử kết quả của bạn không hiển thị các hướng liên quan trong đường dẫn, bởi vì nó không được xác định trong nguồn gốc, mặc dù bạn thấy một số rels bây giờ. – ulkas

Trả lời

0

Về cơ bản, bạn muốn thực hiện xếp hạng chỉ xem xét các mối quan hệ "với luồng đường dẫn". Thật không may, để kiểm tra "với lưu lượng đường dẫn", bạn cần phải kiểm tra chỉ mục đường dẫn của các nút bắt đầu/kết thúc của từng mối quan hệ và chỉ có thể thực hiện với APOC ngay bây giờ.

// allshortestpaths to get all non-cyclic paths 
MATCH path=allshortestpaths((a{id:"1"})-[*]-(b{id:"2"})) 

// Find rank worthy relationships 
WITH path, filter(rl in relationships(path) WHERE apoc.coll.indexOf(path, startnode(rl))<apoc.coll.indexOf(path, endnode(rl)))) as comply 

// Filter results 
RETURN path, REDUCE(rk = 0, rl in comply | rk+rl.followrank) as rank 
ORDER BY rank DESC 

(Tôi không thể kiểm tra phần APOC, vì vậy bạn có thể phải vượt qua các nút (đường dẫn) thay vì đường dẫn đến thủ tục APOC)

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