поиск самого дальнего узла с использованием Neo4j (узел без входящего отношения)

Я создал графическую базу данных в Neo4j и хочу использовать ее для целей обобщения.

Между ними около 500 000 узлов (20 различных меток) и 2,5 миллиона отношений (50 различных типов).

В примере путь: a -> b -> c-> d -> e

Я хочу найти узел без каких-либо входящих отношений (это «а»). И я должен сделать это для всех узлов (нахождение узлов в начале всех возможных путей, не имеющих входящих связей).

Я безуспешно пробовал несколько кодов Cypher:

match (a:type_A)-[r:is_a]->(b:type_A) 
with a,count (r) as count
where count = 0 
set a.isFirst = 'true'

or

match (a:type_A), (b:type_A) 
where not (a)<-[:is_a*..]-(b) 
set a.isFirst = 'true'

В чем проблема?!

Кроме того, я должен создать этот код и в neo4jClient.


person Alirezaaa    schedule 27.03.2014    source источник
comment
Что вы подразумеваете под безуспешно? Что случилось?   -  person starsplusplus    schedule 27.03.2014
comment
только 10% узлов не имеют входящих связей. Но мои запросы возвращают все узлы.   -  person Alirezaaa    schedule 27.03.2014


Ответы (2)


Если вы хотите найти все узлы, у которых нет входящих отношений, вы можете найти их, используя OPTIONAL MATCH:

START n=node(*)
OPTIONAL MATCH n<-[r]-()
WITH n,r
WHERE r IS NULL 
RETURN n
person tstorms    schedule 27.03.2014
comment
@jjaderberg, tstorms спасибо за быстрый ответ. Этот тип узла имеет 65 247 членов, и я знаю, что около 10% из них не имеют входящих отношений. Итак, правильный код должен возвращать около 6500 узлов. Однако все коды, которые я пробовал, включая те, которые вы мне прислали, возвращают ровно 65 247 узлов! Я не знаю, как все узлы находятся в этом запросе. Я изменил ваши коды на: match (a:type_A) OPTIONAL MATCH a <-[r:is_a]-(b:type_A) WHERE r IS NULL RETURN count(distinct a) и match (a:type_A) Where not ()-[:is_a]->a RETURN count( distinct a) Есть подсказки? Лучший, - person Alirezaaa; 27.03.2014
comment
Я отредактировал запрос, WHERE привязан к совпадению, поэтому он применяется внутри совпадения для фильтрации результатов совпадения, которые вы должны добавить впоследствии - person Michael Hunger; 30.03.2014

Ваш первый запрос будет соответствовать только путям, где есть связь [r:is_a], поэтому подсчет r никогда не может быть равен 0. Ваш второй запрос вернет любую произвольную пару узлов, помеченных :typeA, которые не связаны транзитивно [:is_a]. Что вы хотите, так это фильтровать предикат пути. Для общего случая попробуйте

MATCH (a)
WHERE NOT ()-->a

Это примерно переводится как «любой узел, который не имеет входящих отношений». Вы можете указать шаблон с типами, свойствами или метками по мере необходимости, например

MATCH (a:type_A)
WHERE NOT ()-[:is_a]->a
person jjaderberg    schedule 27.03.2014
comment
Возвращаются все узлы (с входящими отношениями или без них). Есть идеи? - person Alirezaaa; 28.03.2014
comment
Если вы запустите первый запрос и вернете a, любой возвращенный узел не будет иметь входящих отношений. Но вы также уточняете свой шаблон такими вещами, как входящие отношения типа такой-то или из узла с меткой такой-то и такой-то, есть вероятность, что там что-то пойдет не так. Вот базовый пример в консоли, начните с него и попытайтесь воспроизвести проблему (вы можете добавьте небольшую выборку собственных данных). - person jjaderberg; 28.03.2014