neo4j CYPHER - 在 JSON 导入期间动态 运行 FOREACH,具体取决于 JSON 元素是否具有某个 属性
neo4j CYPHER - Dynamically run a FOREACH during JSON import depending on whether JSON element has a certain property
为了将 XML 数据导入 neo4j 数据库,我首先将 XML 解析为 python 字典,然后使用 CYPHER 查询,如下所示:
(pmid 有一个 UNIQUE CONSTRAINT)
WITH $pubmed_dict as pubmed_article
UNWIND pubmed_article as particle
MERGE (p:Publication {pmid: particle.MedlineCitation.PMID.text})
ON CREATE SET p.title = COALESCE (particle.MedlineCitation.Article.Journal.Title, particle.MedlineCitation.Article.ArticleTitle)
ON MATCH SET p.title = COALESCE (particle.MedlineCitation.Article.Journal.Title, particle.MedlineCitation.Article.ArticleTitle)
FOREACH (author IN particle.MedlineCitation.Article.AuthorList.Author |
MERGE (a:Author {last_name: COALESCE(author.LastName, 'LAST NAME MISSING!'), first_name: COALESCE(author.ForeName, 'FIRST NAME MISSING!')})
MERGE (p)<-[:WROTE]-(a)
)
FOREACH (ref IN particle.MedlineCitation.CommentsCorrectionsList.CommentsCorrections |
MERGE (cited_p:Publication {pmid: COALESCE (ref.PMID.text, 'NO-PMID')})
MERGE (cited_p)<-[:REFERENCES]-(p)
)
我的粒子具有以下字典结构:
我想在第二个FOREACH循环中实现的是:
如果有 particle.MedlineCitation.CommentsCorrectionsList.CommentsCorrections
列表
并且如果它有一张带有 PMID.text
的地图,
如果具有给定 PMID 的发布已经存在,我希望不会发生任何事情,否则我希望使用给定 PMID 创建新节点。在这两种情况下,我都希望节点在查询开始时从最初创建的 p:Publication 获得关系 REFERENCES。
我还没有找到这种情况的语法,到目前为止唯一的解决方法是使用函数 COALESCE (ref.PMID.text, 'NO-PMID')})
总是创建新的 :REFERENCES 关系到具有没有 PMID 的 CommentsCorrectionsList 的节点。
谁有更好的解决方案?
您可以使用 CASE WHEN THEN
创建一个(非)空集合并在其上使用 FOREACH,这基本上就像一个有条件执行的块。
例如
FOREACH (_ IN case when exists(p.foo) then [true] else [] end |
....
)
为了将 XML 数据导入 neo4j 数据库,我首先将 XML 解析为 python 字典,然后使用 CYPHER 查询,如下所示: (pmid 有一个 UNIQUE CONSTRAINT)
WITH $pubmed_dict as pubmed_article
UNWIND pubmed_article as particle
MERGE (p:Publication {pmid: particle.MedlineCitation.PMID.text})
ON CREATE SET p.title = COALESCE (particle.MedlineCitation.Article.Journal.Title, particle.MedlineCitation.Article.ArticleTitle)
ON MATCH SET p.title = COALESCE (particle.MedlineCitation.Article.Journal.Title, particle.MedlineCitation.Article.ArticleTitle)
FOREACH (author IN particle.MedlineCitation.Article.AuthorList.Author |
MERGE (a:Author {last_name: COALESCE(author.LastName, 'LAST NAME MISSING!'), first_name: COALESCE(author.ForeName, 'FIRST NAME MISSING!')})
MERGE (p)<-[:WROTE]-(a)
)
FOREACH (ref IN particle.MedlineCitation.CommentsCorrectionsList.CommentsCorrections |
MERGE (cited_p:Publication {pmid: COALESCE (ref.PMID.text, 'NO-PMID')})
MERGE (cited_p)<-[:REFERENCES]-(p)
)
我的粒子具有以下字典结构:
我想在第二个FOREACH循环中实现的是:
如果有 particle.MedlineCitation.CommentsCorrectionsList.CommentsCorrections
列表
并且如果它有一张带有 PMID.text
的地图,
如果具有给定 PMID 的发布已经存在,我希望不会发生任何事情,否则我希望使用给定 PMID 创建新节点。在这两种情况下,我都希望节点在查询开始时从最初创建的 p:Publication 获得关系 REFERENCES。
我还没有找到这种情况的语法,到目前为止唯一的解决方法是使用函数 COALESCE (ref.PMID.text, 'NO-PMID')})
总是创建新的 :REFERENCES 关系到具有没有 PMID 的 CommentsCorrectionsList 的节点。
谁有更好的解决方案?
您可以使用 CASE WHEN THEN
创建一个(非)空集合并在其上使用 FOREACH,这基本上就像一个有条件执行的块。
例如
FOREACH (_ IN case when exists(p.foo) then [true] else [] end |
....
)