【问题标题】:Neo4J Schema Constraint Validation FailedNeo4J 架构约束验证失败
【发布时间】:2018-12-23 02:45:01
【问题描述】:

总体背景
我目前正在尝试将 neo4j 查询写入要在烧瓶中使用的函数。
我的目标是让函数从 csv 文件中加载数据,该文件会定期自我更新,并根据需要创建新的节点和关系。

我一直在尝试遵循此处显示的函数结构:
https://github.com/nicolewhite/neo4j-flask/blob/master/blog/models.py

我已经分别测试了 neo4j 密码查询,我目前遇到了两个问题(我将在单独的帖子中发布第二个 py2neo 问题)。

title_id,title  
T1,Article Title 1  
T2,Article Title 2 

我一直在通过手动添加如下行来更改 csv 文件:

title_id,title  
T1,Article Title 1  
T2,Article Title 2 
T3,TEST

我的关键字 csv 文件如下所示:

title_id,keyword_id,keyword  
T1,K1,aaa  
T1,K2,bbb  
T1,K3,ccc  
T1,K4,ddd  
T2,K1,aaa  
T2,K5,eee  
T2,K6,fff  
T2,K4,ddd  

同样,我一直在添加新的关键字进行测试:

title_id,keyword_id,keyword  
T1,K1,aaa  
T1,K2,bbb  
T1,K3,ccc  
T1,K4,ddd  
T2,K1,aaa  
T2,K5,eee  
T2,K6,fff  
T2,K4,ddd  
T2,K7,TEST  

我的约束如下:

CREATE CONSTRAINT ON (a_title:Title) ASSERT a_title.t_id IS UNIQUE  
CREATE CONSTRAINT ON (keyword:Keyword) ASSERT keyword.k_id IS UNIQUE  

我遇到的第一个问题是 LOAD CSV 问题。

我的py2neo代码如下:

def create_titles(self):
    #
    query = '''
    'LOAD CSV WITH HEADERS FROM "file:///1209test_titles.csv" AS csvLine1 WITH csvLine1 ' \
    'WHERE csvLine1.title_id IS NOT NULL MERGE (a_title:Title{t_id:csvLine1.title_id,Title:csvLine1.title})'
    '''


    return graph.run(query)

但是,当我尝试通过将新数据附加到我的 csv 文件来创建一个新的标题节点时,我遇到了一个约束错误,告诉我我刚刚已经存在的节点。

我已尝试按照此处找到的答案进行操作:
Neo4j Load CSV only when unique
我当前在浏览器环境中测试的 LOAD CSV 代码如下:

LOAD CSV WITH HEADERS FROM "file:///1209test_titles.csv" AS csvLine1
WITH csvLine1
WHERE csvLine1.title_id IS NOT NULL
MERGE (a_title:Title)
ON MATCH SET a_title.t_id = csvLine1.title_id
ON MATCH SET a_title.Title = csvLine1.title

...但它仍然给我一个约束错误。

(作为比较,我尝试运行我的关键字密码查询,但它似乎工作正常,没有任何错误)

  query2 = 'LOAD CSV WITH HEADERS FROM 

"file:///1209test_titleid_kwid_kw.csv" AS csvLine3 
WITH csvLine3 WHERE csvLine3.title_id IS NOT NULL   MERGE(keyword:Keyword{k_id:csvLine3.keyword_id,Keyword:csvLine3.keyword})   WITH csvLine3, keyword MATCH(title:Title{t_id:csvLine3.title_id}) MERGE(title)-[r1:HAS_KEYWORDS]->(keyword)'

graph.run(query2)

我不太确定我做错了什么,以及我的关键字节点创建和标题节点创建之间有什么区别......(在检查我的文件后,将信息附加到标题 csv 文件曾经工作。 ..)

非常感谢,

埃里克

【问题讨论】:

    标签: neo4j cypher py2neo


    【解决方案1】:

    您需要使用唯一属性(或多个属性)进行 MERGE,并且只有在 MERGE 之后才能使用 SET 的变体之一。

    您引用的这种方法不起作用:

    LOAD CSV WITH HEADERS FROM "file:///1209test_titles.csv" AS csvLine1
    WITH csvLine1
    WHERE csvLine1.title_id IS NOT NULL
    MERGE (a_title:Title)
    ON MATCH SET a_title.t_id = csvLine1.title_id
    ON MATCH SET a_title.Title = csvLine1.title
    

    此处的 MERGE 将使其匹配与模式匹配的所有内容,因此它将匹配数据库中的所有 :Title 节点,然后在所有节点上设置这些属性(然后在 CSV 中的每一行重复相同的过程)。

    你需要这个:

    LOAD CSV WITH HEADERS FROM "file:///1209test_titles.csv" AS csvLine1
    WITH csvLine1
    WHERE csvLine1.title_id IS NOT NULL
    MERGE (a_title:Title {t_id:csvLine1.title_id})
    ON MATCH SET a_title.Title = csvLine1.title // or just SET if you want to set it in all cases
    

    【讨论】:

    • 啊,谢谢你清楚的解释!我会再读几遍,找出我错的原因!今天下午测试时,我通过删除所有约束暂时解决了这个问题......(当我测试你的代码时,我发现为什么它被认为是不好的做法......虽然我不知道该怎么说就 neo4j 的运作方式而言...
    • 合并可能是一件棘手的事情。另一件要回顾的事情是我们在how MERGE works 上的知识库文章之一
    猜你喜欢
    • 1970-01-01
    • 2018-07-30
    • 2015-05-08
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多