Neo4J, как запросить иерархические данные / переполнение стека

я создал структуру категорий в базе данных графа «neo4j».
У меня есть узлы и отношения, все идеально.

Я использую Neoxygen Neoclient для PHP для доступа к данным. Как я могу эффективно запросить весь граф категорий (включая структуру) из моего корневого элемента?

MATCH (a:`Category`{category_id:0})-[r:HAS_CHILD*]->(b:`Category`)
RETURN b,r

Моя желаемая структура в PHP:
— корень
— Категория А
——— Подкатегория AB
— Категория Б
— категория C
——— Подкатегория CA
—————— Подкатегория CAA

Есть идеи?

Заранее спасибо.

mr_g

1

Решение

Это полностью выполнимо и удобно в NeoClient Neoxygen.

Первое, что нужно сделать, это активировать средство форматирования ответа:

$client = ClientBuilder::create()
->setAutoFormatResponse(true)
->addConnection(xxx...)
->build();

Во-вторых, в отношении вашего запроса я бы определенно установил предел глубины, чтобы избежать поведения памяти в зависимости от связности вашего графа:

MATCH (a:`Category`{category_id:0})-[r:HAS_CHILD*..20]->(b:`Category`)
RETURN b,r

Затем вы можете отправить его клиенту и воспользоваться тем, чтобы клиент переназначил результаты в виде графа:

$query = 'MATCH (a:`Category`{category_id:{id}})-[r:HAS_CHILD*..20]->(b:`Category`)'
RETURN b,r';
$children = $client->sendCypherQuery($q, ['id'=>0])->getResult()->getNodes();

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

$children узлы в первой глубине, так

$rels = $children->getOutboundRelationships();
$nodes = [];
foreach ($rels as $rel) {
$nodes[] = $rel->getEndNode();
}

$ узлов теперь содержит все узлы в глубине 2.

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

3

Другие решения

Cypher возвращает табличные данные, поэтому, если вы хотите получить древовидную иерархию, самый эффективный способ — это вернуть все пути от корня до листьев. Путь является коллекцией / массивом узла- (отношения-узла) * (то есть это нечетное число объектов, всегда содержащих узел на каждом конце с чередующимися узлами и отношениями). Вот шифр того, как вы это сделаете:

MATCH path(a:`Category`{category_id:0})-[r:HAS_CHILD*]->(b:`Category`)
WHERE NOT(b-[:HAS_CHILD]->())
RETURN b,r

WHERE Предложение гарантирует, что вы возвращаете только все пути к листьям. Вы можете вернуть все категории в дереве, которые также дадут вам частичные пути, но все эти частичные пути содержатся в каком-то более длинном пути, так что в итоге вы получите больше данных, чем вам нужно.

Как только у вас есть пути (я не уверен, в какой форме они отображаются в Neoclient, так как я не парень PHP), вы можете построить иерархическую структуру данных в памяти из результатов. Если я правильно помню, структура типа карта / словарь в PHP — это ассоциативный массив.

2

Схема:

Indexes
ON :Category(category_id)   ONLINE (for uniqueness constraint)

Constraints
ON (category:Category) ASSERT category.category_id IS UNIQUE

Запрос:

MATCH(c:Category) RETURN c
0
По вопросам рекламы [email protected]