2013-11-09 5 views
0

Используя neo4j 1.9.2, я пытаюсь найти все узлы в моем графике, которые имеют отношение «один к одному» с другим узлом. Предположим, у меня есть люди на моем графике, и я хотел бы найти всех людей, у которых есть ровно один друг (с 2013 года), и у этого одного друга есть только другой друг, а другой нет. В качестве возвращения я хотел бы иметь все эти пары «изолированных» друзей.Neo4j - Cypher возвращает 1 к 1 отношениям

Я попытался следующие:

START n=node(*) MATCH n-[r:is_friend]-m-[s:is_friend]-n 
WHERE r.since >= 2013 and s.since >= 2013 
WITH n, m, count(r), count(s) 
WHERE count(r) = 1 AND count(s) = 1 
RETURN n, m 

Но этот запрос не то, что он должен сделать - это просто ничего не возвращает.

Примечание: между двумя лицами существует только одно отношение. Таким образом, один друг имеет входящие отношения, а другой - исходящий. Кроме того, эти два человека могут иметь некоторые другие отношения, такие как «works_in» или так, но я просто хочу проверить, существует ли отношение 1: 1 типа * is_friends * между людьми.

EDIT: Предложение Stefan прекрасно работает при использовании узла (*) в качестве отправной точки. Но при попытке этого запроса для одного конкретного узла в качестве начальной точки (например, start n = node (42)), он не работает. Как будет выглядеть решение в этом случае?

Обновление: Я все еще задаюсь вопросом о решении для этого szenario: Как проверить, имеет ли данный начальный узел отношение 1 к 1 другому узлу определенного типа отношений. Есть идеи?

ответ

3

Здесь очень важно понять концепцию путей в предложении MATCH. Путь - это чередующийся набор узла, отношения, узла, отношения, узла .... Существует ограничение того, что одно и то же отношение никогда не будет происходить дважды в одном и том же пути, иначе может возникнуть опасность иметь бесконечные циклы.

Сказали, что вам нужно решить, находится ли в вашем домене is_friend. Если это направлено, вы бы различали друга-друга b и b, являющегося другом a. Из описания я полагаю is_friend неориентированный и утверждение должно выглядеть следующим образом:

START n=node(*) MATCH n-[r:is_friend]-() 
WHERE r.since >= 2013 
WITH n, count(r) as numberOfFriends 
WHERE numberOfFriends=1 
RETURN n 

Вам не придется заботиться о другом конце, он проходится, тем не менее, так как вы делаете node(*). Имейте в виду, что node(*) становится значительно дороже, когда ваш график растет.

+0

Хорошо, вы правы, когда вы начинаете с узла (*), ваше предложение работает нормально. Но как я могу это сделать, начиная с одного стартового узла? Тогда ограничение, что друг имеет только одного друга, не проверяется. Честно говоря, то, что я на самом деле делаю, начинается с подмножества графика. Но все же, для этого случая ваше предложение не возвращает всех изолированных моих друзей во всем графике – user2752625

+0

Как насчет моего редактирования? При запуске с одного конкретного узла запуска, как я могу проверить, имеет ли этот узел запуска только один друг, и этот один друг имеет только стартовый узел в качестве друга и возвращает оба узла, если это так. Любые предложения по этому сценарию? – user2752625

+0

Вы можете использовать опцию 'match':' MATCH n- [r?: Is_friend] -() ', обратите внимание на знак вопроса после' r' –

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