Правильный способ обновления краев в луковицах (neo4j или titan)
Я экспериментирую с Bulbs
для взаимодействия с базой данных графа. (Производство будет использовать Titan, локально Neo4j кажется лучшим для экспериментов).
Я не могу обернуть голову вокруг этой концепции...
Луковицы показывают, как создавать новые вершины...
>>> james = g.vertices.create(name="James")
>>> julie = g.vertices.create(name="Julie")
>>> g.edges.create(james, "knows", julie)
Копаясь в документах, я также могу заменить это на "получить или создать":
>>> james = g.vertices.get_or_create('name',"James",{'name':'james')
Что я не могу понять, так это как получить существующий Edge. До сих пор мои попытки заканчивались воссозданием десятков отношений "Джеймс знает Джули" вместо доступа к существующему для обновления.
Может ли кто-нибудь указать мне правильное направление?
1 ответ
Вы можете добавлять / обновлять свойства ребра, но с помощью графовых баз данных вы не можете обновлять атрибуты, которые делают его ребром, т.е. вы не можете обновлять входящие и исходящие идентификаторы вершин или метки. Вместо этого вы удаляете край и добавляете новый.
Вот различные способы получения и обновления и обновления его свойств.
Вы можете получить преимущество по его ID:
>>> from bulbs.rexster import Graph
>>> g = Graph()
>>> james = g.vertices.create(name="James")
>>> julie = g.vertices.create(name="Julie")
>>> edge = g.edges.create(james, "knows", julie)
>>> edge2 = g.edges.get(edge.eid) # get the edge again
>>> assert edge == edge2
>>> edge2.someprop = "somevalue"
>>> edge2.save()
Вы можете найти ребро по его свойствам, если оно есть, и они проиндексированы:
# will return an iterator or None edges (may return more than one)
>>> edges = g.edges.index.lookup(someprop="somevalue")
>>> edge = edges.next()
>>> edge.someprop = "newvalue"
>>> edge.save()
# will return 1 or None edges (or an error if more than 1 edge found)
>>> edge = g.edges.index.get_unique(someprop="somevalue")
>>> edge.someprop = "newvalue"
>>> edge.save()
Вы также можете получить преимущество, используя Gremlin, пройдя по его вершинам:
>>> from bulbs.rexster import Graph
>>> g = Graph()
>>> script = "g.V('name',name1).outE(label).as('e').inV.has('name',name2).back('e')"
>>> params = dict(name1="James", label="knows", name2="Julie")
>>> edges = g.gremlin.query(script, params)
>>> edge = edges.next()
>>> edge.someprop = "newvalue"
>>> edge.save()
Посмотрите шаблон возврата Гремлин...
- https://github.com/tinkerpop/gremlin/wiki
- https://github.com/tinkerpop/gremlin/wiki/Backtrack-Pattern
- http://bulbflow.com/docs/api/bulbs/gremlin/
- http://bulbflow.com/docs/api/bulbs/rexster/gremlin/
Но самый эффективный способ обновить ребро, когда вы не знаете его ID, - это обновить ребро с помощью скрипта Gremlin, который ищет его (таким образом, у вас есть только одно обращение к серверу, а не два):
>>> from bulbs.rexster import Graph
>>> g = Graph()
>>> script = "g.V('name',name1).outE(label).as('e').inV.has('name',name2).back('e').sideEffect{it.someprop = someprop}"
>>> params = dict(name1="James", label="knows", name2="Julie", someprop="somevalue")
>>> edges = g.gremlin.query(script, params)
>>> edge = edges.next()
>>> edge.someprop
'somevalue'
См. https://github.com/tinkerpop/gremlin/wiki/Updating-a-Graph
И для удобочитаемости, вместо того, чтобы писать строки Gremlin one в Python REPL, я бы поместил свои сценарии Gremlin в gremlin.groovy
файл, как показано здесь:
http://bulbflow.com/docs/api/bulbs/groovy/
Вот реальный пример использования Gremlin для получения или создания преимущества:
https://github.com/espeed/lightbulb/blob/master/lightbulb/gremlin.groovy
И подробное объяснение кода здесь: