2014-12-18 4 views
0

Я пытаюсь выполнить запрос агрегирования по пути переменной длины, где узлы, которые я хочу агрегировать, не находятся в исходном пути, но вместо этого связаны с ними. Например мой путь выглядитNeo4j Variable Length Path и Aggregate Query

MATCH p = (:Visit)-[:NEXT*]->(:Visit) 
RETURN p 

но каждый: узел (посещение) связан с (: Destination)

(:Visit)-[:LOCATION]->(:Destination) 

агрегации Я хочу, чтобы подсчитать общие пути на основе свойства идентификатора узлов назначения, а не посещений. Я придумал, как использовать Союз, чтобы объединить множество путей фиксированной длины Результаты

MATCH (d1:Destination)--(v1:Visit), (d2:Destination)--(v2:Visit) 
WHERE (v1:Visit)-[:NEXT]->(v2:Visit) 
RETURN [d1.id,d2.id] AS Path, count(*) AS PathCount 
UNION 
MATCH (d1:Destination)--(v1:Visit), (d2:Destination)--(v2:Visit), (d3:Destination)--(v3:Visit) 
WHERE (v1:Visit)-[:NEXT]->(v2:Visit)-[:NEXT]->(v3:Visit) 
RETURN [d1.id,d2.id,d3.id] AS Path, count(*) AS PathCount 
UNION ... 

Но это не очень хорошее решение, если пути являются скажем длиной 200, и я беспокоюсь о производительности используя множество Союзов.

Я создал Neo4j GIST здесь с данными выборки: http://gist.neo4j.org/?a8ab894c5c9740a94747

образца данных

CREATE 
// Destinations. 
(d1:Destination {id:'A'}), 
(d2:Destination {id:'B'}), 
(d3:Destination {id:'C'}), 
(d4:Destination {id:'D'}), 
(d5:Destination {id:'E'}), 
(d6:Destination {id:'F'}), 
// First Route 
(v1:Visit {time:1}), 
(v2:Visit {time:2}), 
(v3:Visit {time:3}), 
(v4:Visit {time:4}), 
(v5:Visit {time:5}), 
(v1)-[:LOCATION]->(d1), 
(v2)-[:LOCATION]->(d2), 
(v3)-[:LOCATION]->(d3), 
(v4)-[:LOCATION]->(d4), 
(v5)-[:LOCATION]->(d6), 
(v1)-[:NEXT]->(v2)-[:NEXT]->(v3)-[:NEXT]->(v4)-[:NEXT]->(v5), 
// Second Route 
(v6:Visit {time:10}), 
(v7:Visit {time:21}), 
(v8:Visit {time:23}), 
(v10:Visit {time:45}), 
(v6)-[:LOCATION]->(d1), 
(v7)-[:LOCATION]->(d2), 
(v8)-[:LOCATION]->(d4), 
(v9)-[:LOCATION]->(d6), 
(v10)-[:LOCATION]->(d5), 
(v11)-[:LOCATION]->(d3), 
(v6)-[:NEXT]->(v7)-[:NEXT]->(v8)-[:NEXT]->(v9)-[:NEXT]->(v10)-[:NEXT]->(v11); 

Ожидаемый результат

Path PathCount 
[A, B] 2 
[D, F] 1 
[B, D] 1 
[B, C] 1 
[C, D] 1 
[B, C, D] 1 
[C, D, F] 1 
[A, B, C] 1 
[A, B, D] 1 
... many more 

ответ

0

ли следующая работа для вас? Он возвращает голову каждого пути как PathHead, упорядоченную коллекцию всех остальных узлов в пути, как PathTail, и количество шагов в пути, как PathCount.

MATCH (d1:Destination)<-[:LOCATION]-(v1:Visit)-[:NEXT*]->(:Visit)-[:LOCATION]->(d2:Destination) 
RETURN d1.id as PathHead, COLLECT(d2.id) AS PathTail, COUNT(*) AS PathCount 
+0

Жаль, что этот запрос не поможет. Только первый и последний пункт назначения включен в каждый из путей. Кроме того, я был неясно в вопросе, я хотел, чтобы количество путей, которые имеют одинаковые адресаты, не длина одного пути. – Shawn

+0

Я верю, что мой запрос возвращает все адресаты на пути. Я проверил его с вашими типовыми данными, и я отредактировал свой ответ, чтобы показать результаты. Вы хотите сказать, что вы действительно хотите знать, для каждого места назначения, сколько путей содержит его? Или вы хотите что-то еще? – cybersam

+0

Ваш запрос возвращает только 4 строки, а один из них имеет длину 7, где самый длинный путь в образцах данных - длина 6. Я хочу найти подсчеты для количества раз, когда путь (любой длины) посетил. Я ожидаю (из выборочных данных) набор результатов из многих путей от длины 2-6 с PathCount не более 2, который был бы для [A, B], который является единственным общим путем между двумя примерами маршрутов. – Shawn