Почему одно отношение neo4j отображается дважды в результатах запроса cypher?

Рассмотрим тривиальный граф с направленной связью:

CREATE 
  (`0` :Car {value:"Ford"})
, (`1` :Car {value:"Subaru"})
, (`0`)-[:`DOCUMENT` {value:"DOC-1"}]->(`1`);

Следующий запрос MATCH (n1:Car)-[r:DOCUMENT]-(n2:Car) RETURN * возвращает:

╒══════════════════╤══════════════════╤═════════════════╕
│"n1"              │"n2"              │"r"              │
╞══════════════════╪══════════════════╪═════════════════╡
│{"value":"Subaru"}│{"value":"Ford"}  │{"value":"DOC-1"}│
├──────────────────┼──────────────────┼─────────────────┤
│{"value":"Ford"}  │{"value":"Subaru"}│{"value":"DOC-1"}│
└──────────────────┴──────────────────┴─────────────────┘

График определяет только отношение Ford->Subaru, почему два отношения?
Как интерпретировать обратное (строка 1; не указано в CREATE) утверждение?

Примечание: Это продолжение Преобразование нескольких отношений между двумя узлами в одну с весом, о котором я просил ранее. Я решил свою проблему, но не уверен, что мой ответ - лучшее решение.

0
0
383
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш оператор MATCH здесь не указывает направление, поэтому есть два возможных пути, которые будут соответствовать шаблону (помните, что порядок узлов в пути важен и отличает пути друг от друга), поэтому ваши два ответа.

Если вместо этого вы укажете направление отношений, вы обнаружите, что существует только один возможный путь, который соответствует:

MATCH (n1:Car)-[r:DOCUMENT]->(n2:Car) 
RETURN *

Что касается вопроса о том, почему мы получаем два пути назад, когда мы опускаем направление, помните, что пути чувствительны к порядку: два пути, которые имеют одинаковые элементы, но с разным порядком элементов, являются разными путями.

Чтобы лучше понять это, рассмотрите следующие два вопроса:

# Query 1
MATCH (n1:Car)-[r:DOCUMENT]-(n2:Car) 
WHERE n1.value = 'Ford'
RETURN *

╒══════════════════╤══════════════════╤═════════════════╕
│"n1"              │"n2"              │"r"              │
╞══════════════════╪══════════════════╪═════════════════╡
│{"value":"Ford"}  │{"value":"Subaru"}│{"value":"DOC-1"}│
└──────────────────┴──────────────────┴─────────────────┘

# Query 2
MATCH (n1:Car)-[r:DOCUMENT]-(n2:Car) 
WHERE n1.value = 'Subaru'
RETURN *

╒══════════════════╤══════════════════╤═════════════════╕
│"n1"              │"n2"              │"r"              │
╞══════════════════╪══════════════════╪═════════════════╡
│{"value":"Subaru"}│{"value":"Ford"}  │{"value":"DOC-1"}│
└──────────────────┴──────────────────┴─────────────────┘

Концептуально (а также используется планировщиком при отсутствии индексов), чтобы получить каждый из приведенных выше результатов, вы начинаете с результатов полного соответствия, как в вашем описании, а затем фильтруете до единственного, которое соответствует заданным критериям.

Вышеупомянутые результаты не будут согласованы с исходным запросом на бесперспективное сопоставление, если исходный запрос вернул только одну строку вместо двух.


Дополнительная информация из ОП

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

When your pattern contains a bound relationship, and that relationship pattern doesn’t specify direction, Cypher will try to match the relationship in both directions.

MATCH (a)-[r]-(b)
WHERE id(r)= 0
RETURN a,b

This returns the two connected nodes, once as the start node, and once as the end node.

Для меня запрос без указанного направления означает соответствовать любому направлению, которое вы найдете на графике, но это должна быть связь, которая действительно существует. Какой смысл возвращать несуществующий?

Marek Grzenkowicz 11.08.2018 08:51

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

InverseFalcon 11.08.2018 11:47

Вот что меня смущает - я создаю 3 объекта (2 узла и 1 отношение), а затем запрос возвращает 4 объекта. Я ищу аналог SELECT * в мире отношений.

Marek Grzenkowicz 11.08.2018 20:00

Запрос возвращает те же объекты, только в другом порядке. Есть два возможных пути, соответствующих данному шаблону, включая одни и те же узлы и одно и то же отношение, разница в начальном и конечном узлах пути. Пути чувствительны к порядку. Если вы хотите применить только один возможный способ прохождения через отношения, вам нужно иметь для него направление.

InverseFalcon 11.08.2018 23:03

Другие вопросы по теме