2016-06-27 5 views
1

У меня есть простой родительский/дочерний граф в neo4j. Я хотел бы найти родителей (и его детей) со значением свойства в родительском узле или в дочернем узле. Родитель может иметь (или нет) список детейNeo4j: поиск в дочерних тоже

Я попробовал этот запрос

MATCH (p:Parent) 
WHERE p.lastName =~ "(?i).*.*" 
RETURN p AS parent, [] as children 
UNION 
MATCH (p:Parent) - [:REL] -> (c:Child) 
WHERE p.lastName =~ "(?i).*1234.*" OR c.name =~ "(?i).*.*" 
RETURN p AS parent, c AS collect(children) 

, но она не совершенна: этот запрос возвращал не отчетливый результат.

Знаете ли вы, что лучший запрос содержит список родителей и его детей со значением свойства в родительском узле или дочернем узле.

Логика должна быть:

if (p.lastName == x) OR (p.children.name == x) 
    return p  

UPDATE

Я даю вам больше элементов:

Пример:

(p1:Parent { lastName: "AAA" }) no children 

(p2:Parent { lastName: "BBB" }) 2 children 
    (c1:Child { name: "CCC" }) 
    (c2:Child { name: "DDD"}) 

Если я выполнить этот запрос

MATCH (p:Parent) 
OPTIONAL MATCH (p)-[:REL]->(c:Child) 
WHERE p.lastName CONTAINS 'DDD' OR c.name CONTAINS 'DDD' 
RETURN p AS parent, collect(c) AS children; 

Результатом является p1, p2 с c2. Я хотел бы только p2 с c2

ответ

3

Я предполагаю, что у вас есть опечатки в паре ваших регулярных выражений, и что все они должны быть на самом деле "(?i).*1234.*».

[ОБНОВЛЕНО ДВАЖДЫ]

В Cypher , предложение UNIONаддитивно комбинаты привести строки, которая объясняет, почему вы не получите отличные результаты

Этот запрос может быть ближе к тому, что вы хотите:.

MATCH (p1:Parent) 
WHERE p1.lastName CONTAINS 'DDD' 
OPTIONAL MATCH (p1)-[:REL]->(c1:Child) 
WITH COLLECT({parent: p1, child: c1}) AS x 
OPTIONAL MATCH (p2:Parent)-[:REL]->(c2:Child) 
WHERE c2.name CONTAINS 'DDD' AND NOT(p2.lastName CONTAINS 'DDD') 
WITH x + (CASE WHEN p2 IS NULL THEN [] ELSE COLLECT({parent: p2, child: c2}) END) AS y 
UNWIND y AS z 
RETURN z.parent AS parent, COLLECT(z.child) AS children; 

Это первый собирает все Parent узлы, имеющие нужную lastName, наряду с их Child узлов, если таковые имеются. Затем он присоединяет к этой коллекции все пары узлов Parent/Child, где у родителя нет соответствующего lastName, но у ребенка есть нужный name. Наконец, он возвращает каждый отдельный узел Parent вместе с его узлами Child.

+0

Ваш запрос лучше, но не идеален: ваш запрос всегда возвращает весь родительский узел, даже если предложение where не проверено для участника – aGO

+0

Я обновил свой ответ. – cybersam

+0

Это похоже на мой запрос. Единственное различие заключается в том, что вместо = ~ – aGO

Смежные вопросы