neo4j py 2neo:具有多个键/值的Graph.find_one

ih99xse1  于 2022-11-23  发布在  其他
关注(0)|答案(3)|浏览(163)

我在使用py 2neo find和find_one(http://py2neo.org/2.0/essentials.html)时遇到一些问题
我想在Cypher中实现的是:

MATCH (p:Person) WHERE p.name='Alice' AND p.age=22 RETURN p

比如,有多个键/值集(例如,如果图中有多个“Alice”)。
我的问题是,我不知道该给予graph.find_one什么,一个工作代码是:

graph.find_one('Person', 'name', 'Alice')

我想要的是这样的东西(这是行不通的!):

graph.find_one('Person', {'name': 'Alice', 'age': 22})

一个可能的(不好的)解决方案是创建一个graph.find,然后循环遍历results属性并查找年龄,但我不喜欢这个解决方案。

**额外好处:**有没有可能用graph.find来做一些像年龄〉25的事情?
编辑:新“解决方案”

如果p.name。

>>> tx = graph.cypher.begin()
>>> tx.append(find_person, {'N': 'Alice', 'A': 22})
>>> res = tx.process()
>>> print(res[0][0][0])
(n423:Person {age:22,name:"Lisa"})

我不喜欢的是我错过了Note对象,(我不完全理解RecordListList,以及如何导航它)

u0sqgete

u0sqgete1#

如果您查看源代码,您会发现findfind_one不支持这种类型的查询。

d = {'name': 'Alice', 'age' : 22}

# quote string values
d = {k:"'{}'".format(v) if isinstance(v, basestring) else v 
                     for k,v in d.items()}

cond = ' AND '.join("p.{}={}".format(prop, value) for prop, value in d.items())

query = "MATCH (p:Person) {condition} RETURN p"
query = query.format(condition=cond)
# "MATCH (p:Person) p.age=22 AND p.name='Alice' RETURN p"
results = graph.cypher.execute(query)
guicsvcw

guicsvcw2#

基于@elyase的答案和原始的py2neo.Graph.find,我做了这段代码.请随时评论和改进..:-)

def find_dict(graph, label, key_value=None, limit=None):
    """ Iterate through a set of labelled nodes, optionally filtering
    by property key/value dictionary
    """
    if not label:
        raise ValueError("Empty label")
    from py2neo.cypher.lang import cypher_escape
    if key_value is None:
        statement = "MATCH (n:%s) RETURN n,labels(n)" % cypher_escape(label)
    else:
        # quote string values
        d = {k: "'{}'".format(v) if isinstance(v, str) else v
             for k, v in key_value.items()}

        cond = ""
        for prop, value in d.items():
            if not isinstance(value, tuple):
                value = ('=', value)

            if cond == "":
                cond += "n.{prop}{value[0]}{value[1]}".format(
                    prop=prop,
                    value=value,
                )
            else:
                cond += " AND n.{prop}{value[0]}{value[1]}".format(
                    prop=prop,
                    value=value,
                )

        statement = "MATCH (n:%s ) WHERE %s RETURN n,labels(n)" % (
            cypher_escape(label), cond)
    if limit:
        statement += " LIMIT %s" % limit
    response = graph.cypher.post(statement)
    for record in response.content["data"]:
        dehydrated = record[0]
        dehydrated.setdefault("metadata", {})["labels"] = record[1]
        yield graph.hydrate(dehydrated)
    response.close()

def find_dict_one(graph, label, key_value=None):
    """ Find a single node by label and optional property. This method is
    intended to be used with a unique constraint and does not fail if more
    than one matching node is found.
    """
    for node in find_dict(graph, label, key_value, limit=1):
        return node

使用find_dict_one:

>>> a = find_dict_one(graph, 'Person', {'name': 'Lisa', 'age': 23})
>>>     print(a)
(n1:Person {age:23,name:"Lisa"})

将find_dict与元组一起使用:

>>> a = find_dict(graph, 'Person', {'age': ('>', 21)}, 2)    >>> for i in a:
>>>     print(i)
(n2:Person {age:22,name:"Bart"})
(n1:Person {age:23,name:"Lisa"})

使用不带元组的find_dict:

>>> a = find_dict(graph, 'Person', {'age': 22}, 2)    >>> for i in a:
>>>     print(i)
(n2:Person {age:22,name:"Bart"})
vhipe2zx

vhipe2zx3#

可以使用节点匹配器

person_node = NodeMatcher(gdb).match("Person").where(name=pname).first()

相关问题