Получение всех отношений между соседями узла

У меня есть встроенный граф db узлов (пользователи твиттера) и направленных ребер (следует).

Я пытаюсь установить все отношения между пользователями (набор A), за которыми следует указанный пользователь (узел U). Также отношения между узлами в A и указанным узлом U.

Мой запрос:

START u=node:user_id(user_id={id_of_U})
MATCH p = u-->following, p2= following-[?]->u, p3 = following-[?]->()<--u
RETURN distinct rels(p),rels(p2),rels(p3) 

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

Я перепробовал множество запросов, и приведенный выше запрос пока что лучший. Тем не менее, я уверен, что есть более эффективные способы сделать это, потому что, когда я получаю эти отношения в java-методе, просматривая всех пользователей в «A», получая все отношения для каждого из них (Direction.BOTH), а затем фильтрация отношений с помощью «A» (удаление отношений, у которых есть начальный или конечный узел, не принадлежащий «A»), для пользователя, следующего за 500 людьми, требуется всего 8 секунд, тогда как запрос шифрования не может даже потерпеть неудачу, не взорвав мою кучу ...


person cagdas    schedule 04.02.2013    source источник


Ответы (2)


Вы можете попробовать это?

start u=node:user_id(user_id={id_of_U})
MATCH u-[r]->following
with u, r, following
match following-[r2?]->u, following-[r3?]->()<-[r4]-u
RETURN distinct r, r2, r3, r4

Кроме того, вы используете последнюю версию 1.9?

person Eve Freeman    schedule 04.02.2013
comment
Я использовал 1.8.1, но теперь обновился до 1.9 и попробовал ваш запрос, но ничего не изменилось ... - person cagdas; 04.02.2013

начало с p = u-->following не оптимально, так как оно берет все связанные узлы, а позже вы пытаетесь фильтровать эти узлы. Я бы посоветовал собрать меньше узлов, а затем немного расширить этот набор:

START u=node:user_id(user_id={id_of_U})
MATCH u-[:FOLLOWS]->following
WITH u,following
MATCH u-[r]-following
RETURN distinct r;

это даст вам все отношения между узлами в setA, за которыми также следует узел U.

в случае, если у вас нет отношения ПОСЛЕДУЮЩИЕ на вашем графике - вы должны иметь, иначе дизайн вашего графика не будет оптимальным. Я заметил, что вы не используете какой-либо конкретный тип rel в своем запросе - это может быть оптимальным тогда и только тогда, когда у вас есть только 1 тип отношений в ваших данных. насколько я понимаю ваш вопрос, у вас более 1 типа rel.

изменить:

START u=node:user_id(user_id={id_of_U})
MATCH u-[]-following
WITH u, following
MATCH u-[r]-again, again-[r2]-following
RETURN r, r2
person ulkas    schedule 04.02.2013
comment
Ваш запрос дает только отношения между u и _2 _... Я хочу также получить все отношения между _3 _-_ 4_, где following[m] и following[n] являются элементами набора A. И это сложная часть, с которой я не могу справиться. (кстати, у моего графика один тип отношений, СЛЕДУЕТ) - person cagdas; 04.02.2013
comment
спасибо, я обновил свой ответ, дело в том, чтобы сопоставить setA два раза с двумя разными переменными, а затем сопоставить также rels между этими переменными. в случае, если это все еще достигнет предела кучи, я боюсь, что единственный способ пройти через это - использовать gremlin и строго определить алгоритм. - person ulkas; 04.02.2013
comment
на самом деле предложенный вами запрос вызвал ошибку кучи, но добавление еще одного WITH решило эту проблему. START u=node:user_id(user_id='109537107') MATCH u-[]->following WITH u, following MATCH u-[r]->again WITH following,again,r MATCH again-[r3]->following RETURN r,r3 однако я сделал еще одну реализацию, в которой сначала я получаю все идентификаторы узлов, за которыми u следует. затем передайте их дважды в качестве параметра, например START u=node({nodeIdList}), u2= node({nodeIdList2}) MATCH u-[r]->u2, u2-[r2]->u RETURN distinct r,r2, это обеспечило самое быстрое решение. может стоит дождаться новых версий neo4j ... - person cagdas; 05.02.2013
comment
но ваше предложение использовать WITH важно и заставило меня немного лучше понять, как работает cypher. большое спасибо. Если через несколько дней ни один другой ответ не поможет, я приму ваш ответ как решение проблемы. Я просто хочу подождать и убедиться, что у нас нет лучшего варианта. - person cagdas; 05.02.2013
comment
хорошая работа по обновлению запроса. иногда некоторые проблемы не могут быть решены с помощью neo4j полезным способом - например, когда есть суперузел или количество элементов, сопоставленных в запросе, слишком велико - это вычислительная проблема, а не программная, и поэтому я ' Боюсь, что neo4j в этом никогда не поправится. в таких случаях я бы порекомендовал создать свой собственный алгоритм графа с использованием gremlin или использовать совершенно другую технологию, потенциально apache hadoop с minhash на кластере серверов. - person ulkas; 05.02.2013