2015-01-20 3 views
0

У меня есть следующий код python для создания графика в neo4j. Я использую py2neo версии 2.0.3., соединяющий узлы с отношениями в py2neo

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. Я хотел бы сделать свойство узлов auth_name узлом как индекс для соединения с узлами Mainstream_news. Любые предложения будут замечательными.

ответ

4

Вы создаете новый узел Authors каждый раз через свой цикл, даже если узел Author (с теми же свойствами) уже существует.

Во-первых, я думаю, вы должны создать ограничения уникальности на Authors(auth_name) и Mainstream_News(id), чтобы обеспечить выполнение ваших требований. Это только должно быть сделано один раз. Ограничение уникальности также автоматически создает индекс для вас, что является бонусом.

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

Но вы, вероятно, придется опустошить ваш DB первый (по крайней мере, из всех Authors и Mainstream_News узлов и их отношений), так как я полагаю, что в настоящее время имеет много дублирующих узлов.

Затем вы можете использовать merge_one и create_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)) 
+0

Очень большое указывающий уникальной реализация ограничений, но все еще получают странные ошибки при использовании merge_one: TypeError: merge_one() занимает не более 4 аргументов (8 данных) –

+0

Я обновил свой ответ. – cybersam

0

Это то, что я обычно делаю, как я считаю, что легче знать, что происходит. Насколько я знаю, есть, но когда вы создаете_уника только с узлом, и нет необходимости создавать узлы, когда вам также нужно создать ребро.

У меня нет базы данных на этом компьютере, поэтому, пожалуйста, медведь со мной, если есть какие-то опечатки, я исправлю это утром, но, думаю, вы скорее получите быстрый ответ. . :-)

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 

Я включил первые строки дерева, чтобы сделать его более общим. Он возвращает узел-объект или None.


EDIT:

использование

@cybersam из схемы прохладно, осуществить это, я буду стараться использовать его myselfe также .. :-)

Вы можете прочитать больше о он здесь: http://neo4j.com/docs/stable/query-constraints.html http://py2neo.org/2.0/schema.html

Смежные вопросы