繁体   English   中英

neo4j CYPHER-在ON MATCH SET上根据条件创建新节点

[英]neo4j CYPHER - at ON MATCH SET create new nodes on condition

要将XML数据导入neo4j DB,我首先将XML解析为python字典,然后使用CYPHER查询:

WITH $pubmed_dict as pubmed_article
UNWIND pubmed_article as particle
...
FOREACH (author IN particle.MedlineCitation.Article.AuthorList.Author |
  MERGE (a:Author {last_name: COALESCE(author.LastName, 'LAST NAME MISSING!')})
  ON CREATE SET a.first_name = author.ForeName, a.affiliation = author.AffiliationInfo.Affiliation
  ON MATCH SET a.first_name = author.ForeName, a.affiliation = author.AffiliationInfo.Affiliation
  MERGE (p)<-[:WROTE]-(a)      
)

不幸的是,作者在数据库中没有唯一的ID,因此可能是不同的作者具有相同的姓氏,但名字首字母或从属关系不同。

...
                <Author ValidYN="Y">
                    <LastName>Smith</LastName>
                    <ForeName>A L</ForeName>
                    <Initials>AL</Initials>
                    <AffiliationInfo>
                        <Affiliation>University X</Affiliation>
                    </AffiliationInfo>
                </Author>
...
                <Author ValidYN="Y">
                    <LastName>Smith</LastName>
                    <ForeName>A L</ForeName>
                    <Initials>AL</Initials>
                    <AffiliationInfo>
                        <Affiliation>University BUMBABU</Affiliation>
                    </AffiliationInfo>
                </Author>

我的意图是在author.LastName上合并,但在MATCH上检查作者是否具有相同的ForeName或相同的从属关系,如果不是,则创建一个新节点。

我该如何使用CYPHER查询呢?

编辑1

节点密钥约束是解决方案,不过这是企业版的功能。 寻找一种解决方法。

编辑2

这段代码几乎可以正常工作:

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)      
    )

总结一下:如果LastName或ForeName或从属关系不同,那么我想为每个作者创建一个新作者。 对于姓氏缺失的作者,我还需要新节点! 和名字丢失!

如果没有关键节点约束,是否有可能获得此结果? (因为这是企业版功能...)

您可以使用约束,然后neo4j将为您检查唯一性。

文档

要创建节点密钥,请确保所有带有特定标签的节点都具有一组定义的属性,这些属性的组合值是唯一的,并且该组中的所有属性都存在

CREATE CONSTRAINT ON (author:Author)  ASSERT (author.first_name, author.last_name, author.affiliation) IS NODE KEY

作者在Neo4j中确实有一个唯一的ID,即节点ID。 可以用来标识节点,然后设置属性。 也许是这样的:

Match (a:Author{LastName:'xxx',ForeName:'yyy'}) 
with a, id(a) as ID
where ID > -1
match (b) where id(b)=ID set b.first_name = author.ForeName, b.affiliation = author.AffiliationInfo.Affiliation

节点的ID不一定是稳定的或可预测的,因此您必须在使用它之前直接访问它。

因为使用的是python代码,所以最好使用全局查询来下拉作者节点数据:

match (a:Author{LastName:'xxx',ForeName:'yyy'})  return a.LastName,a.ForeName,id(a) as ID

然后,您可以编写一个csv文件来批量上传所需的信息。 csv可能如下所示:

> "ID","ForeName","LastName","Affiliation" 
"26","David","Smith","Johns Hopkins" 
etc.

python代码可以过滤不需要处理的节点。

然后加载文件:

LOAD CVS with HEADER file:///'xxx.csv' as line 
match (a) where id(a)=toInteger(line.ID) 
set a.Affiliation=line.toString(line.Affiliation")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM