Neo4j: как передать переменную в свойство Neo4j Apoc (apoc.path.subgraphAll)

Я новичок в Neo4j и пытаюсь сделать POC, реализовав графическую базу данных для корпоративной справочной / интеграционной архитектуры (архитектура, в которой все корпоративные приложения представлены в виде узлов, базовые таблицы / API - логически сгруппированы в виде узлов, интеграции между приложениями в виде отношений.

Цель состоит в том, чтобы беспрепятственно выполнить "Анализ воздействия", используя преимущества Graph DB (Примечание: я понимаю, что это может быть неправильным подходом для достижения того, что я пытаюсь достичь, поэтому предложения приветствуются)

Позвольте мне кратко ответить на мой вопрос,

Есть четыре приложения - A1, A2, A3, A4; A1 имеет набор таблиц (представленных узлом A1TS1), который обновляется интеграцией 1 (отношения в данном случае), и тот же набор таблиц считывается интеграцией 2. Таким образом, модель данных выглядит следующим образом

(A1TS1)<-[:INT1]-(A1)<-[:INT1]-(A2)
(A1TS1)-[:INT2]->(A1)-[:INT2]->(A4)

У меня есть имена таблиц базовых приложений, захваченных как свойство List в узле A1TS1.

Допустим, одна таблица приложения изменена для нового столбца или типа данных, и я хотел понять все затронутые интеграции и приложения. Теперь я пытаюсь написать запрос, как показано ниже, чтобы извлечь все узлы и отношения, которые связаны / затронуты из-за этого изменения таблицы, но не в состоянии этого достичь

Ожидаемый результат - все затронутые узлы (A1TS1, A1, A2, A4) и отношения (INT1, INT2)

Вариант 1 (с использованием APOC)

MATCH (a {TCName:'A1TS1',AppName:'A1'})-[r]-(b) 
WITH a as STRTND, Collect(type(r)) as allr 
CALL apoc.path.subgraphAll(STRTND, {relationshipFilter:allr}) YIELD nodes, relationships 
RETURN nodes, relationships

Это сбой с ошибкой Failed to invoke procedure 'apoc.path.subgraphAll': Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String

Вариант 2 (Использование с, раскрутить, собирать предложение)

MATCH (a {TCName:'A1TS1',AppName:'A1'})-[r]-(b) 
WITH a as STRTND, Collect(r) as allr 
UNWIND allr as rels 
MATCH p=()-[rels]-()-[rels]-() 
RETURN p

Это приводит к ошибке "Невозможно использовать одну и ту же переменную отношения" rels "для нескольких шаблонов", но если я использую [rels] один раз, как p=()-[rels]=() это работает, но не дает мне все узлы

Любая помощь / предложение / руководство приветствуется. заранее спасибо

ОбновлениеПопытка дать больше контекста, показывая основные данные

MATCH (TC:TBLCON) RETURN TC

"TC"
{"Tables":["TBL1","TBL2","TBL3"],"TCName":"A1TS1","AppName":"A1"}  
{"Tables":["TBL4","TBL1"],"TCName":"A2TS1","AppName":"A2"} 

MATCH (A:App) RETURN A

"A"                                                                   
{"Sponsor":"XY","Platform":"Oracle","TechOwnr":"VV","Version":"12","Tags":["ERP","OracleEBS","FinanceSystem"],"AppName":"A1"}               
{"Sponsor":"CC","Platform":"Teradata","TechOwnr":"RZ","Tags":["EDW","DataWarehouse"],"AppName":"A2"}   

MATCH ()-[r]-() RETURN distinct r.relname

"r.relname"
"FINREP"   │  (runs between A1 to other apps)
"UPFRNT"   │  (runs between A2 to different Salesforce App)
"INVOICE"  │  (runs between A1 to other apps)

Это то, что я пытаюсь достичь. Предположим, что "TBL3" изменяется в приложении A1, я хотел написать запрос с указанием таблицы "TBL3" в шаблоне соответствия, получить все связанные отношения и связанные узлы (в восходящем направлении).

Может быть, мне нужно выполнить 3 шага, Шаг 1 - Написать шаблон соответствия, чтобы найти начальный узел и связанные отношения Шаг 2 - Сохранить эти отношения из шага 1 в переменной / параметре Array Шаг 3 - Пропустить начальный узел с шага 1 и параметр с шага 2 до apoc.path.subgraphAll, чтобы увидеть все затронутые узлы

Концептуально это может показаться обоснованным, но вопрос о том, как сделать это технически в запросе neo4j Cypher, является вопросом.

Надеюсь это поможет

2 ответа

Решение

С ответом киберзамка следующий запрос дает мне то, что я хочу. Единственным ограничением является то, что этот результат ограничен 3 слоями (3-й уровень через опциональное соответствие)

MATCH (TC:TBLCON) WHERE 'TBL3' IN TC.Tables 
CALL apoc.path.subgraphAll(TC, {maxLevel:1}) YIELD nodes AS invN, relationships AS invR
WITH TC, REDUCE (tmpL=[], tmpr IN invR | tmpL+type(tmpr)) AS impR
MATCH FLP=(TC)-[]-()-[FLR]-(SL) WHERE type(FLR) IN impR 
WITH FLP, TC, SL,impR 
OPTIONAL MATCH SLP=(SL)-[SLR]-() WHERE type(SLR) IN impR RETURN FLP,SLP

Это работает для моих нужд, надеюсь, это также может кому-то помочь.

Спасибо всем за ответы и предложения

****Обновить****

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

MATCH (initTC:TBLCON) WHERE $TL IN initTC.Tables 
WITH Reduce(O="",OO in Reduce (I=[], II in collect(apoc.node.relationship.types(initTC)) | I+II) | O+OO+"|") as RF
MATCH (TC:TBLCON) WHERE $TL IN TC.Tables 
CALL apoc.path.subgraphAll(TC,{relationshipFilter:RF}) YIELD nodes, relationships
RETURN nodes, relationships

Спасибо всем (особенно киберсам)

Этот запрос может делать то, что вы хотите:

MATCH (tc:TBLCON)
WHERE $table IN tc.Tables
MATCH p=(tc)-[:Foo*]-()
WITH tc,
  REDUCE(s = [], x IN COLLECT(NODES(p)) | s + x) AS ns,
  REDUCE(t = [], y IN COLLECT(RELATIONSHIPS(p)) | t + y) AS rs
UNWIND ns AS n
WITH tc, rs, COLLECT(DISTINCT n) AS nodes
UNWIND rs AS rel
RETURN tc, nodes, COLLECT(DISTINCT rel) AS rels;

Предполагается, что вы предоставляете имя таблицы интереса (например, "TBL3") в качестве значения table параметр. Это также предполагает, что все отношения интересов имеют Foo тип.

Сначала находит tc, TBLCON узлы, содержащие это имя таблицы. Затем он использует ненаправленный поиск переменной длины для всех путей (с неповторяющимися связями), которые включают tc, Затем он использует COLLECT дважды: объединить список узлов в каждом пути и объединить список отношений в каждом пути. Каждый результат агрегации будет представлять собой список списков, поэтому он использует REDUCE в каждом внешнем списке, чтобы объединить внутренние списки. Затем он использует UNWIND а также COLLECT(DISTINCT x) в каждом списке, чтобы создать список с уникальными элементами.

[ОБНОВИТЬ]

Если вы различаете ваши отношения по типу (а не по значению свойства), ваш Cypher-код может быть намного проще благодаря использованию функций APOC. В следующем запросе предполагается, что требуемые типы отношений передаются через types параметр:

MATCH (tc:TBLCON)
WHERE $table IN tc.Tables
CALL apoc.path.subgraphAll(
  tc, {relationshipFilter: apoc.text.join($types, '|')}) YIELD nodes, relationships
RETURN nodes, relationships;
Другие вопросы по тегам