Как получить подграф первых соседей в neo4j?

Я выбираю первые n соседей узла с этим запросом в neo4j: (в этом примере n = 6)

У меня есть взвешенный график, и поэтому я также упорядочиваю результаты по весу:

START start_node=node(1859988)
MATCH start_node-[rel]-(neighbor)
RETURN DISTINCT neighbor,
rel.weight AS weight ORDER BY proximity DESC LIMIT 6;

Я хотел бы получить целый подграф, включая вторых соседей (первых соседей первых шести детей).

Я пробовал smtg как:

START start_node=node(1859988)
MATCH start_node-[rel]-(neighbor)
FOREACH (neighbor | MATCH neighbor-[rel2]-(neighbor2) )
RETURN DISTINCT neighbor1, neighbor2, rel.proximity AS proximity ORDER BY proximity DESC LIMIT 6, rel2.proximity AS proximity ORDER BY proximity DESC LIMIT 6;

синтаксис все еще неправильный, но я также не уверен в выводе: я хотел бы иметь таблицу кортежей parent, children и weight: [node_A - node_B - weight]

Я хотел бы видеть, выполняет ли он лучше один запрос или шесть запросов. Может кто-нибудь помочь в разъяснении, как выполнить итерацию запроса (FOREACH) и отформатировать вывод?

благодарю вас!

2 ответа

Решение

Хорошо, я думаю, что понимаю. Вот еще одна попытка, основанная на вашем комментарии:

MATCH (start_node)-[rel]-(neighbor)
WHERE ID(start_node) IN {source_ids}
WITH
  neighbor, rel
ORDER BY rel.proximity
WITH
  collect({neighbor: neighbor, rel: rel})[0..6] AS neighbors_and_rels
UNWIND neighbors_and_rels AS neighbor_and_rel
WITH
  neighbor_and_rel.neighbor AS neighbor,
  neighbor_and_rel.rel AS rel
MATCH neighbor-[rel2]-(neighbor2)
WITH
  neighbor,
  rel,
  neighbor2,
  rel2
ORDER BY rel.proximity
WITH
  neighbor,
  rel,
  collect([neighbor2, rel2])[0..6] AS neighbors_and_rels2
UNWIND neighbors_and_rels2 AS neighbor_and_rel2
RETURN
  neighbor,
  rel,
  neighbor_and_rel2[0] AS neighbor2,
  neighbor_and_rel2[1] AS rel2

Это немного долго, но, надеюсь, это даст вам хотя бы идею

Во-первых, вы должны избегать использования START, поскольку он (надеюсь) со временем исчезнет.

Таким образом, чтобы получить окрестность, вы можете использовать пути переменной длины, чтобы убрать все пути от узла

MATCH path=start_node-[rel*1..3]-(neighbor)
WHERE ID(start_node) = 1859988
RETURN path, nodes(path) AS nodes, EXTRACT(rel IN rels(path) | rel.weight) AS weights;

Затем вы можете взять путь / узлы и объединить их в памяти с вашим языком по вашему выбору.

РЕДАКТИРОВАТЬ:

Также взгляните на этот SO вопрос: получить дерево с Neo4j

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

Другие вопросы по тегам