Установить ограничение на свойство отношения для поиска по переменному пути в GraphDB

#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]