저는 neo4j 드라이버를 사용하여 node.js에서 neo4j 쿼리를 실행하고 있습니다. 많은 정보가 무의미한 정보를 삭제하기 위해 단순화되었지만 필요한 것은 여기에 있습니다.UNWIND를 사용하여 MATCH와 두 개의 FOREACH로 구성된 블록을 실행하는 방법은 무엇입니까?
는교육 과정 : 간행물의 목록이
는 출판 :는 게시에 대한 데이터를 포함 나는 다음과 같이 정의, 몇 가지 단점과 데이터 세트를 섭취하는 쿼리를 만들려고 한
그리고 저자
의 목록저자 인 필드 : 관련 필드는 외부 ID 및 정규화 된 전체 이름.
는 외부 ID은 데이터의 출처 시스템에서 오는 ID입니다. 존재하는 것으로 보장되지 않지만이 경우, 그것은 고유 항상 존재하는 노드
normalizedFullName을 확인하고이 나타나는 곳마다 항상 같은 이름을 가질 것 같은 저자를 가정하는 괜찮습니다; 그것은 또한 전체 이름이 고유하지 않을 수 있음을 허용하고이 어떤 점에서 서로 다른 두 사람이 같은 노드로 저장 될 수
저자 발행물의 일부가 될 것은 단지 그것을 normalizedFullName입니다 가능합니다 및 으로 정규화 된 전체 이름 및 externalId으로 다른 사람의 일부가 될 수 있습니다. 보시다시피, 매우 일관된 데이터는 아니지만, 필요한 끝 부분에는 문제가되지 않습니다.이 부분은 사소한 게시를 병합
모두에게 병합
"curriculum": [ { "data": { "fieldA": "a", "fieldB": "b" }, "authors": [ { "externalId": "", "normalizedFullName": "namea namea" }, { "externalId": "123456", "normalizedFullName": "nameb nameb" } ] }, { "data": { "fieldA": "d", "fieldB": "e" }, "authors": [ { "externalId": "123321", "normalizedFullName": "namea namea" }, { "externalId": "123456", "normalizedFullName": "nameb nameb" } ] } ]
(구문 오류 상관 없어)하지만, 일이 복잡 :
은 다음과 같이 표시됩니다 저자를 합병하기 위해이 논리 (단순화 한 것)를 따라야하기 때문에 저자에게 올 때 :
IF author don't have externalId OR isn't already a node created with his externalId THEN
merge by normalizedFullName
ELSE IF there is already a node with this externalId THEN
merge by externalId
그래서, "이 foreach는 속임수"에 의해 달성 될 수 있다는 것을 발견, 내가 조건부 병합의 어떤 종류를 필요로한다고 인정, 나는 (의견을 명확히하기 위해 추가)이 작은 괴물을 마련 할 수 있었다 :
// For each publication, merge it
UNWIND {publications} as publication
MERGE (p:Publication { fieldA: publication.data.fieldA, fieldB: publication.data.fieldB })
ON CREATE SET p = publication.data
WITH p, publication.authors AS authors
// Then, for each author in this publication
UNWIND authors AS author
// IF author don't have externalId OR isn't already a node created with his externalId THEN
MATCH (a:Author) WHERE a.externalId = author.data.externalId AND a.externalId <> '' WITH count(a) as found, author, p
// Merge by name
FOREACH(ignoreMe IN CASE WHEN found = 0 THEN [1] ELSE [] END |
MERGE (aa:Author { normalizedFullName: author.data.normalizedFullName })
ON CREATE SET aa = author.data
MERGE (aa)-[:CONTRIBUTED]->(p)
)
// Else, merge by externalId
FOREACH(ignoreMe IN CASE WHEN found > 0 THEN [1] ELSE [] END |
MERGE (aa:Author { externalId: autor.dadta.externalId })
ON CREATE SET aa = author.data
MERGE (aa)-[:CONTRIBUTED]->(p)
)
참고 : 이것은 실제 검색어가 아니며 정확한 구조를 보여줍니다.
문제점
그것은 작동하지 않습니다. 출판물은 (corretly) 작성하고 저자는 절대 작성하지 않습니다.MATCH, FOREACH 또는 둘 다의 조합이 UNWIND 때문에 일어날 것으로 예상되는 루프를 어지럽히는 것 같습니다.
나는 제대로 할 수있는 방법을 찾지 못했습니다. 나는 또한 무엇이 잘못되었는지를 발견 할 수 없으며 심지어 이용 가능한 문서를 점검한다.
그럼 어떻게해야합니까?
어떤 통찰력 사전에
감사 (나를 더 이상 정보가 필요한 경우 알려주세요)!
는 여기 재현 할 수있는 작업 예를 가지고 있습니까? 매우 유용 할 것입니다! 감사! –
나는 약 12 시간 안에 무엇인가를 함께 집어 넣을 수있을 것이다. 고맙습니다! –