1) Получить массив стран на пути с возможными дубликатами: REDUCE
2) Удалить дубликаты и сравнить размеры массивов: UNWIND
+ COLLECT(DISTINCT...)
MATCH path = (start:Person)-[:FRIENDSHIP*1..20]->(person:Person)
WHERE start.id = 128 AND start.country <> "Uganda"
WITH path,
REDUCE(acc=[], n IN NODES(path) | acc + n.country) AS countries
UNWIND countries AS country
WITH path,
countries, COLLECT(DISTINCT country) AS distinctCountries
WHERE SIZE(countries) = SIZE(distinctCountries)
RETURN path
P.S. REDUCE
можно заменить EXTRACT
(благодаря Габора Szarnyas):
MATCH path = (start:Person)-[:FRIENDSHIP*1..20]->(person:Person)
WHERE start.id = 128 AND start.country <> "Uganda"
WITH path,
EXTRACT(n IN NODES(path) | n.country) AS countries
UNWIND countries AS country
WITH path,
countries, COLLECT(DISTINCT country) AS distinctCountries
WHERE SIZE(countries) = SIZE(distinctCountries)
RETURN path
P.P.S. Еще раз спасибо Gabor Szarnyas за дополнительную идею для упрощения запроса:
MATCH path = (start:Person)-[:FRIENDSHIP*1..20]->(person:Person)
WHERE start.id = 128 AND start.country <> "Uganda"
WITH path
UNWIND NODES(path) AS person
WITH path,
COLLECT(DISTINCT person.country) as distinctCountries
WHERE LENGTH(path) + 1 = SIZE(distinctCountries)
RETURN path
Благодарим вас за ответ! Будет ли это лучшим выбором с точки зрения производительности? У меня будет очень большой набор данных с до миллиона узлов. Есть ли способ ускорить запрос? –
@VolodymyrBakhmatiuk Самая тяжелая часть запроса - первая «MATCH»: «MATCH path = (start: Person) - [: FRIENDSHIP * 1..20] -> (person: Person) WHERE start.id = 128 И начать .country <> «Уганда». В настоящее время не совсем понятно, как его улучшить ... –
@VolodymyrBakhmatiuk Тестирование пути самая простая часть ... –