【问题标题】:connecting the nodes with relationships in py2neo用py2neo中的关系连接节点
【发布时间】:2015-01-20 17:30:00
【问题描述】:

我有以下 python 代码在 neo4j 中制作图表。我使用的是 py2neo 2.0.3 版。

 import json
    from py2neo import neo4j, Node, Relationship, Graph

    graph = neo4j.Graph("http://localhost:7474/db/data/")
       with open("example.json") as f:
        for line in f:
            while True:
                try:
                    file = json.loads(line)
                    break
                except ValueError:
                    # Not yet a complete JSON value
                    line += next(f)

                    # Now creating the node and relationships

            news, = graph.create(Node("Mainstream_News", id=unicode(file["_id"]), entry_url=unicode(file["entry_url"]),
                                      title=unicode(file["title"])))  # Comma unpacks length-1 tuple.
            authors, = graph.create(
                Node("Authors", auth_name=unicode(file["auth_name"]), auth_url=unicode(file["auth_url"]),
                     auth_eml=unicode(file["auth_eml"])))

            graph.create(Relationship(news, "hasAuthor", authors ))

我可以创建一个图表,其中包含节点 Mainstream_News 和 Authors 以及关系“hasAuthor”。我的问题是,当我这样做时,我有一个 Mainstream_News 节点和一个作者,但实际上一个作者节点有多个 Mainstream_News。我想将 Author 节点的 auth_name 属性作为连接 Mainstream_news 节点的索引。任何建议都会很棒。

【问题讨论】:

    标签: neo4j py2neo


    【解决方案1】:

    您每次循环都会创建一个新的Authors 节点,即使作者节点(具有相同的属性)已经存在。

    首先,我认为您应该在 Authors(auth_name)Mainstream_News(id) 上创建唯一性约束,以强制执行您的要求。这只需一次。唯一性约束还会自动为您创建索引,这是一个奖励。

    graph.schema.create_uniqueness_constraint("Authors", "auth_name")
    graph.schema.create_uniqueness_constraint("Mainstream_News", "id")
    

    但您可能必须先清空您的数据库(至少在所有 AuthorsMainstream_News 节点及其关系中),因为我认为它目前有很多重复节点。

    然后,您可以使用merge_onecreate_unique API 来防止重复节点和关系:

    news = graph.merge_one("Mainstream_News", "id", unicode(file["_id"]))
    news.properties["entry_url"] = unicode(file["entry_url"])
    news.properties["title"] = unicode(file["title"])
    
    authors = graph.merge_one("Authors", "auth_name", unicode(file["auth_name"]))
    news.properties["auth_url"] = unicode(file["auth_url"])
    news.properties["auth_eml"] = unicode(file["auth_eml"])
    
    graph.create_unique(Relationship(news, "hasAuthor", authors))
    

    【讨论】:

    • 非常好的指向唯一约束实现,但在使用 merge_one 时仍然出现奇怪的错误:TypeError: merge_one() 最多需要 4 个参数(给定 8 个)
    【解决方案2】:

    这是我通常做的,因为我发现更容易知道发生了什么。据我所知,有一个但是当你 create_unique 只有一个节点,并且不需要创建节点时,你还必须创建一个边。

    我这台电脑上没有数据库,所以请多多包涵,如果有错别字,我会在早上更正,但我想你宁愿有一个快速的答案.. :-)

    news = graph.cypher.execute_one('MATCH (m:Mainstream_News) '
        'WHERE m.id = {id} '
        'RETURN p'.format(id=unicode(file["_id"])))
    
    if not news:
       news = Node("Mainstream_News")
       news.properties['id] = unicode(file["_id"])
       news.properties['entry_url'] = unicode(file["entry_url"])
       news.properties['title'] = unicode(file["title"])
    
    # You can make a for-loop here
    authors = Node("Authors")
    authors.properties['auth_name'] = unicode(file["auth_name"])
    authors.properties['auth_url'] = unicode(file["auth_url"])
    authors.properties['auth_eml'] = unicode(file["auth_eml"])
    
    rel = Relationship(new, "hasAuthor", authors)
    graph.create_unique(rel)
    # For-loop should end here
    

    我已经包含了树的第一行,使其更通用。它返回一个节点对象或无。


    编辑

    @cybersam 使用模式很酷,实现它,我自己也会尝试使用它.. :-)

    您可以在此处阅读更多信息: http://neo4j.com/docs/stable/query-constraints.html http://py2neo.org/2.0/schema.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多