py2neo - How can I use merge_one function along wi

2019-07-22 17:23发布

I have overcome the problem of avoiding the creation of duplicate nodes on my DB with the use of merge_one functions which works like that:

t=graph.merge_one("User","ID","someID") 

which creates the node with unique ID. My problem is that I can't find a way to add multiple attributes/properties to my node along with the ID which is added automatically (date for example). I have managed to achieve this the old "duplicate" way but it doesn't work now since merge_one can't accept more arguments! Any ideas???

3条回答
Anthone
2楼-- · 2019-07-22 17:46

Graph.merge_one only allows you to specify one key-value pair because it's meant to be used with a uniqueness constraint on a node label and property. Is there anything wrong with finding the node by its unique id with merge_one and then setting the properties?

t = graph.merge_one("User", "ID", "someID")
t['name'] = 'Nicole'
t['age'] = 23
t.push()
查看更多
SAY GOODBYE
3楼-- · 2019-07-22 17:52

This hacky function will iterate through the properties and values and labels gradually eliminating all nodes that don't match each criteria submitted. The final result will be a list of all (if any) nodes that match all the properties and labels supplied.

def find_multiProp(graph, *labels, **properties):
    results = None
    for l in labels:
        for k,v in properties.iteritems():
            if results == None:
                genNodes = lambda l,k,v: graph.find(l, property_key=k, property_value=v)
                results = [r for r in genNodes(l,k,v)]
                continue
            prevResults = results
            results = [n for n in genNodes(l,k,v) if n in prevResults]
    return results

The final result can be used to assess uniqueness and (if empty) create a new node, by combining the two functions together...

def merge_one_multiProp(graph, *labels, **properties):
    r = find_multiProp(graph, *labels, **properties)
    if not r:
        # remove tuple association
        node,= graph.create(Node(*labels, **properties))
    else:
        node = r[0]
    return node

example...

from py2neo import Node, Graph
graph = Graph()

properties = {'p1':'v1', 'p2':'v2'}
labels = ('label1', 'label2')

graph.create(Node(*labels, **properties))
for l in labels:
    graph.create(Node(l, **properties))
graph.create(Node(*labels, p1='v1'))

node = merge_one_multiProp(graph, *labels, **properties)
查看更多
看我几分像从前
4楼-- · 2019-07-22 17:56

I know I am a bit late... but still useful I think

Using py2neo==2.0.7 and the docs (about Node.properties):

... and the latter is an instance of PropertySet which extends dict.

So the following worked for me:

m = graph.merge_one("Model", "mid", MID_SR)
m.properties.update({
    'vendor':"XX",
    'model':"XYZ",
    'software':"OS",
    'modelVersion':"",
    'hardware':"",
    'softwareVesion':"12.06"
})

graph.push(m)
查看更多
登录 后发表回答