#neo4j
#neo4j
Вопрос:
У меня есть график neo4j, который по структуре похож на приведенный ниже пример:
MATCH (n:Person)-[k:KNOWS]->(f)
WHERE k.since < 2000
RETURN f.name, f.age, f.email
что прямо вытекает из примеров neo4j.
Что я хочу сделать, так это следующее: начните с одного узла по имени (в данном случае «Дженнифер») и найдите все узлы, независимо от глубины пути, которые происходят из начального узла, но где, как известно, отношение имеет свойство с <2000, поэтому Дженнифер может знать Гэри с 2000 года, которыйтакже знает Билла еще до 2000 года. И Дженнифер знает Мишель еще до 2000 года (и так далее)
Вот где я застрял:
MATCH p=(n:Person {name:'Jennifer'})-[:KNOWS*]-(f)
RETURN [k IN p WHERE k.since < 2000]
Если я выполняю любой запрос с помощью :KNOWS* , он просто зависает навсегда, даже для относительно небольшой базы данных из 21 узла и 840 связей.
Я подумал, что мне нужно как-то использовать С REDUCE(), но он не щелкает…
Может ли кто-нибудь указать мне правильное направление здесь? Многое изменилось!
Ответ №1:
Вы можете использовать предикат all()
списка, чтобы убедиться, что все отношения в пути соответствуют предикату. Это будет оцениваться во время расширения, поэтому может повысить производительность:
MATCH p=(n:Person {name:'Jennifer'})-[:KNOWS*]-(f)
WHERE all(rel in relationships(p) WHERE rel.since < 2000)
RETURN DISTINCT f
Тем не менее, Cypher занимается поиском всех возможных путей, которые соответствуют шаблону, и этот подход не всегда подходит, когда вас интересуют отдельные узлы, а не отдельные пути (особенно когда пути возвращаются к ранее посещенным узлам через разные отношения).
Возможно, вы захотите добавить верхний предел к вашему расширению переменной длины.
Комментарии:
1. Спасибо, это работает хорошо. Я думаю, что моей самой большой проблемой была проблема человеческого мышления как человека, а не как компьютера. Моя фактическая база данных имеет 2,8 млн связей, и запрашивать у нее бесконечную длину пути — большая ошибка. В итоге я использовал
:[:KNOWS*1..3]