#neo4j #cypher
Вопрос:
У меня есть этот зашифрованный код:
MATCH path = (me:Person {uuid: '{my_id}'})-[:friendship*2]->(p:Person)-[:courses]->(c:Course)
WHERE p.uuid<>'{my_id}'
RETURN distinct(c) as courses
Этот код возвращает все курсы каждого человека в отношениях *2. Но как я могу получить только аналогичные курсы для этих Людей?
Пример фокса: Человек1 имеет: Курс1, Курс2, Курс3.
Человек2 имеет: Курс2, Курс3, Курс4
Мой код вернется [Course1, Course2, Course3, Course4]
, но мне нужно [Course2, Course3]
(только взаимное)
Спасибо за ответы.
Обновление 1: Вот моя версия:
MATCH (me:Person {uuid: '{my_id}'})-[:friendship*2]->(p:Person)-[cr:courses]->(c:Course)
WITH collect(p) as persons, collect(cr) as courses_rel, g, collect(c) as courses
WHERE p.uuid<>'{my_id}' and all(rel in courses_rel WHERE all(person in persons WHERE startNode(rel) = person ))
RETURN courses
этот код работает, но возвращает неправильные данные без фильтрации
Мне нужно пройти 3 курса: Ackerman, 27 Pines Golf Course, 18 Mile Creek Golf
Комментарии:
1. Таким образом, он не должен ничего возвращать в случае, если среди всех отношений *r нет общих курсов?
2. да, мне нужны только общие курсы
Ответ №1:
Во-первых, найдите всех отдельных людей на уровне 2 и все отдельные курсы, которые у них есть. Передайте эти значения в следующую часть запроса с помощью WITH
.
Затем для каждого из этих курсов проверьте, есть ли all
у людей это или нет.
MATCH path = (me:Person {uuid: '{my_id}'})-[:friendship*2]->(p:Person)-[:courses]->(c:Course)
WHERE p.uuid<>'{my_id}'
WITH collect(distinct(c)) as courses, collect(distinct(p)) as persons
MATCH (c:Course)
WHERE c in courses and all(p in persons where (p)-[:courses]->(c))
RETURN c as courses
ИЗМЕНИТЬ:
В случае, если вам нужны курсы, которые были добавлены по крайней мере двумя друзьями, затем найдите количество человек для каждого курса и отфильтруйте их.
MATCH path = (me:Person {uuid: '{my_id}'})-[:friendship*2]->(p:Person)-[:courses]->(c:Course)
WHERE p.uuid<>'{my_id}'
WITH course, collect(distinct(p)) as persons
WHERE size(persons) >= 2
RETURN collect(course) as courses
Комментарии:
1. Большое спасибо!!, это работает) Мой код был похож, но он не работал 🙁 .
2. К сожалению, этот код для меня тоже не работает. Если у меня есть два друга, и у них есть 2 общих клубы, тогда это работает, но если у меня есть вторая пара друзей: 3 и 4 друг друга, и у них совершенно разные клубы, в общем, тогда этот код будет возвращать пустой список, потому что
WHERE c in courses and all(p in persons where (p)-[:courses]->(c))
код будет возвращать только те курсы, в которых каждый друг, а мне как раз нужен клубы, которые были добавлены, по меньшей мере, двух друзей. Есть какие-нибудь идеи?3. Раджендра Кадам, я добавил скриншот
4. Я думал, что это распространено среди всех друзей
5. Обновлен ответ
Ответ №2:
Тогда вам также нужно будет соответствовать вашим курсам. Вы можете повторно использовать одну и ту же переменную, чтобы получить только общие курсы:
MATCH (c:Course)<-[:courses]-(me:Person {uuid: '{my_id}'})-[:friendship*2]->(p:Person)-[:courses]->(c)
WHERE p.uuid<>'{my_id}'
RETURN distinct(c) as courses