2016-04-18 2 views
1

Рассмотрите следующие узлы, которые связаны между собой двумя типами ребер: прямые и пересекающиеся. Запрос должен обнаружить все возможные пути между 2 узлами, который удовлетворяет все следующие правила:Neo4j: совпадение с множественными отношениями своевременно

  • 0..n прямых края
  • 0..1 пересекаться краем
  • пересекаться краем может быть между прямыми краями

Эти пути считаются действительными между nodeZ и узла а:

  • (nodeA)-[:direct]->(nodeB)-[:direct]->(nodeC)->[:direct]->(nodeZ)
  • (nodeA)-[:intersect]->(nodeB)-[:direct]->(nodeC)->[:direct]->(nodeZ)
  • (nodeA)-[:direct]->(nodeB)-[:intersect]->(nodeC)->[:direct]->(nodeZ)
  • (nodeA)-[:direct]->(nodeB)->[:direct]->(nodeC)-[:intersect]->(nodeZ)

В основном пересекаются край может произойти где угодно в пути, но только один раз. Мой идеальный монограмма запрос в несуществующей версии Neo4j бы это:.

MATCH (from)-[:direct*0..N|:intersect*0..1]->(to)

Но Neo4j не поддерживает несколько ограничений для типа ребер :(

UPDATE 23.04.16

Здесь 6609 узлов (из общего объема 550 тыс.), 5184 краев типа прямого (всего 440 тыс.) И 34119 типа пересекаются (из общего количества 37289). Ожидаются некоторые циклические ссылки (которые избегают нео-4j, не так ли ?)

Запрос, который выглядел многообещающим, но не смог закончить в манере секунд:

MATCH p = (from {from: 1})-[:direct|intersect*0..]->(to {to: 99}) WHERE 123 < from.departureTS < 123 + 86400 //next day AND REDUCE(s = 0, x IN RELATIONSHIPS(p) | CASE TYPE(x) WHEN 'intersect' THEN s + 1 ELSE s END) <= 1 return p;

ответ

1

Это будет делать то, что вы хотите:

// Cybersam's correction: 
MATCH p = ((from)-[:direct*0..]->(middle)-[:intersect*0..1]->(middle2)-[:direct*0..]->(to)‌​) return DISTINCT p; 
return p 

Вот тестовый сценарий я использовал:

create (a:nodeA {name: "A"}) 
create (b:nodeB {name: "B"}) 
create (c:nodeC {name: "C"}) 
create (z:nodeZ {name: "Z"}) 

merge (a)-[:direct  {name: "D11"}]->(b)-[:direct  {name: "D21"}]->(c)-[:direct  {name: "D31"}]->(z) 
merge (a)-[:intersect {name: "I12"}]->(b)-[:direct  {name: "D22"}]->(c)-[:direct  {name: "D32"}]->(z) 
merge (a)-[:direct  {name: "D13"}]->(b)-[:intersect {name: "I23"}]->(c)-[:direct  {name: "D33"}]->(z) 
merge (a)-[:direct  {name: "D14"}]->(b)-[:direct  {name: "D24"}]->(c)-[:intersect {name: "I34"}]->(z) 
merge (a)-[:intersect {name: "I15"}]->(z) 

// Cybersam's correction: 
MATCH p = ((from)-[:direct*0..]->(middle)-[:intersect*0..1]->(middle2)-[:direct*0..]->(to)‌​) return DISTINCT p; 
return p 

Я сделал ошибку, считая, что график в браузере отражает данные, которые были вернувшись в «p» - это не так, вам нужно посмотреть часть «строк» ​​отчета, чтобы получить все подробности.

Этот запрос также возвращает отдельные узлы, которые соответствуют требованиям.

+0

Ваш запрос не соответствует указанным требованиям. Он возвращает только пути, начинающиеся по крайней мере с одного «прямого», за которым следует «пересечение», за которым следует, по крайней мере, один «прямой» в конце.Вы можете изменить его, чтобы правильно работать (но это может быть не так хорошо, как мой ответ): 'MATCH p = ((from) - [: direct * 0 ..] -> (middle) - [: intersect * 0. .1] -> (middle2) - [: direct * 0 ..] -> (to)) return DISTINCT p; ' – cybersam

+0

Единственное требование, которое это имеет, состоит в том, что на графике существует пересекающееся ребро, которое это делает. Если ребро пересечения также необязательно, то [: intersect] можно заменить на [: intersect *]. –

+0

'intersect' не требуется [0..1], а также' direct' [0..N]. И нет требования, чтобы путь должен начинаться и заканчиваться «прямым». – cybersam

2

Вот запрос, который соответствует установленным требованиям:

MATCH p = (from)-[:direct|intersect*0..]->(to) 
WHERE REDUCE(s = 0, x IN RELATIONSHIPS(p) | 
    CASE WHEN TYPE(x) = 'intersect' THEN s + 1 ELSE s END) <= 1 
return p; 

Он возвращает все пути с 0 или более direct отношений и 0 или 1 intersect отношений.

+0

Я пробовал, но он никогда не заканчивался (я оставил его работать как минимум полчаса). Пожалуйста, проверьте обновленный вопрос с некоторыми соображениями. – mente

+0

добавил запрос, который я попробовал на исходный вопрос – mente

+0

, может быть, это так плохо из-за круговых ссылок? – mente

Смежные вопросы