I am trying to access neo4j using neo4j python driver.I am running the following code to get a property of a thing A., I open the driver and session directly from GraphDatabase of neo4j and use session.run() to execute graph queries. These queries return a BoltStatementResult object.My question is how this object can be converted to actual result that I need(Property of thing A).?
from neo4j import GraphDatabase
uri = "bolt://abc:7687"
driver = GraphDatabase.driver(uri, auth=("neo4j", "password"))
def matchQuestion(tx, intent,thing):
result = tx.run("MATCH (e:thing) WHERE e.name = {thing}"
"RETURN e.description", thing=thing)
print(result)
with driver.session() as session:
session.read_transaction(matchQuestion, "define","A")
result = tx.run("MATCH (e:thing) WHERE e.name = {thing}"
"RETURN e.description AS description", thing=thing)
for line in result:
print line["description"]
or
print result.single()
You could also specify the item position like -
print result.single()[0]
Related
I want to pass parameter in CREATE using Python
e.g:
'''
n = "abc"
a = 1234
cqlCreate = "CREATE (cornell:university { name: $n,yob:$a})"
''''
but it dosen't work.. any suggestions please
It actually depends on the Python driver that you are using to connect to Neo4j (check https://neo4j.com/developer/python/ to see the list of available drivers). If you are using the official neo4j-driver, the code you wrote is correct. In order execute the Cypher query, you could do something like this:
from neo4j import GraphDatabase
uri = # insert neo4j uri
user = # insert neo4j username
password = # insert neo4j password
n = "abc"
a = 1234
query = "CREATE (cornell:university { name: $n,yob:$a})"
driver = GraphDatabase.driver(uri, auth=(user, password))
session = driver.session()
result = session.run(query, n=n, a=a)
session.close()
driver.close()
Although âńōŋŷXmoůŜ's answer will probably work, it is not recommended way to it.
See also:
https://neo4j.com/docs/api/python-driver/current/api.html
You can use the f-strings in Python. See example below. Note that
You need to use {{ as escape character for {
2 You need to use \ as escape character for "
n = "abc"
a = 1234
cqlCreate = f"CREATE (cornell:university {{name: \"{n}\", yob: {a}}})"
print (cqlCreate)
Result:
CREATE (cornell:university {name: "abc", yob: 1234})
reference: https://www.python.org/dev/peps/pep-0498/
I want to return data in JSON format from Flask method. My Code is written in Flask and Neo4j is used for storing Data.
As of now, my code is:
result = session.run("MATCH (p:Person {name:$username})-[:PURCHASED]->(:Product)<-[:PURCHASED]-(p2:Person)-[:PURCHASED]->(pd2:Product)"
"WHERE NOT (p)-[:PURCHASED]->(pd2)"
"RETURN pd2.title as product_title, pd2.description as product_details" , username=username)
for record in result:
print("%s %s" % (record["product_title"], record["product_details"]))
return 'Loop Entered'
return 'OK'
I tried using 'jsonify' as below but got Type error as : TypeError: ('product_title', 'product_details')
return jsonify([record[("product_title","product_details")] for record in result])
Please let me know what I am missing here.
Maybe you wanted to do this:
return jsonify({record["product_title"]: record["product_details"] for record in result})
or even
return jsonify([
{
"product_title": record["product_title"],
"product_details": record["product_details"],
}
for record in result
])
?
You can access only one key at a time when using dict type in Python
Based on example from Neo4j
from neo4j.v1 import GraphDatabase, basic_auth
driver = GraphDatabase.driver("bolt://localhost", auth=basic_auth("neo4j", "neo4j"))
session = driver.session()
session.run("CREATE (a:Person {name:'Arthur', title:'King'})")
result = session.run("MATCH (a:Person) WHERE a.name = 'Arthur' RETURN a.name AS name, a.title AS title")
for record in result:
print("%s %s" % (record["title"], record["name"]))
session.close()
Here result is of datatype neo4j.v1.session.StatementResult. How to access this data in pandas dataframe without explicitly iterating?
pd.DataFrame.from_records(result) doesn't seem to help.
This is what I have using list comprehension
resultlist = [[record['title'], record['name']] for record in result]
pd.DataFrame.from_records(resultlist, columns=['title', 'name'])
The best I can come up with is a list comprehension similar to yours, but less verbose:
df = pd.DataFrame([r.values() for r in result], columns=result.keys())
The py2neo package seems to be more suitable for DataFrames, as it's fairly straightforward to return a list of dictionaries. Here's the equivalent code using py2neo:
import py2neo
# Some of these keyword arguments are unnecessary, as they are the default values.
graph = py2neo.Graph(bolt=True, host='localhost', user='neo4j', password='neo4j')
graph.run("CREATE (a:Person {name:'Arthur', title:'King'})")
query = "MATCH (a:Person) WHERE a.name = 'Arthur' RETURN a.name AS name, a.title AS title"
df = pd.DataFrame(graph.data(query))
Casting result records into dictionaries does the trick:
df = pd.DataFrame([dict(record) for record in result])
What about:
from neo4j.v1 import GraphDatabase
from pandas import DataFrame
uri = "bolt://localhost:7687"
driver = GraphDatabase.driver(uri, auth=("",""))
get_instances = """MATCH (n)--(m)
RETURN n
LIMIT 10
"""
with driver.session() as graphDB_Session:
result = graphDB_Session.run(get_instances)
df = DataFrame(result.records(), columns=result.keys())
Works for me.
In the V4 of py2neo, the conversion to pandas DataFrame is even easier.
import py2neo
# Some of these keyword arguments are unnecessary, as they are the default values.
graph = py2neo.Graph(uri, user=username, password=password)
df = graph.run("Your query goes here").to_data_frame()
I have a command written in python using the py2neo to access the name of an exchange. This works.
graph = Graph()
stmt = 'MATCH (i:Index{uniqueID: 'SPY'})-[r:belongsTo]->(e:Exchange) RETURN e.name'
exchName = graph.cypher.execute(stmt)[0][0]
Can this be converted to a BOLT neo4j-driver statement? I always get an error. I want to avoid an iterator statement where I loop through the StatementResult.
driver = GraphDatabase.driver("bolt://localhost", auth=basic_auth("neo4j", "neo4j"))
session = driver.session()
stmt = 'MATCH (i:Index{uniqueID: 'SPY'})-[r:belongsTo]->(e:Exchange) RETURN e.name'
exchName = session.run(stmt)[0][0]
TypeError: 'StatementResult' object is not subscriptable
Try to store the results of session.run() in a list to retain them:
driver = GraphDatabase.driver("bolt://localhost", auth=basic_auth("neo4j", "neo4j"))
session = driver.session()
stmt = 'MATCH (i:Index{uniqueID: 'SPY'})-[r:belongsTo]->(e:Exchange) RETURN e.name'
# transform to list to retain result
exchName = list(session.run(stmt))[0][0]
See the docs: http://neo4j.com/docs/developer-manual/current/#result-retain
I'm trying to run the following Cypher query in neomodel:
MATCH (b1:Bal { text:'flame' }), (b2:Bal { text:'candle' }),
p = shortestPath((b1)-[*..15]-(b2))
RETURN p
which works great on neo4j via the server console. It returns 3 nodes with two relationships connecting. However, when I attempt the following in python:
# Py2Neo version of cypher query in python
from py2neo import neo4j
graph_db = neo4j.GraphDatabaseService()
shortest_path_text = "MATCH (b1:Bal { text:'flame' }), (b2:Bal { text:'candle' }), p = shortestPath((b1)-[*..15]-(b2)) RETURN p"
results = neo4j.CypherQuery(graph_db, shortest_path_text).execute()
or
# neomodel version of cypher query in python
from neomodel import db
shortest_path_text = "MATCH (b1:Bal { text:'flame' }), (b2:Bal { text:'candle' }), p = shortestPath((b1)-[*..15]-(b2)) RETURN p"
results, meta = db.cypher_query(shortest_path_text)
both give the following error:
/Library/Python/2.7/site-packages/neomodel-1.0.1-py2.7.egg/neomodel/util.py in _hydrated(data)
73 elif obj_type == 'relationship':
74 return Rel(data)
---> 75 raise NotImplemented("Don't know how to inflate: " + repr(data))
76 elif neo4j.is_collection(data):
77 return type(data)([_hydrated(datum) for datum in data])
TypeError: 'NotImplementedType' object is not callable
which makes sense considering neomodel is based on py2neo.
The main question is how to get a shortestPath query to work via either of these? Is there a better method within python? or is cypher the best way to do it?
edit:
I also tried the following from here which gave the same error.
graph_db = neo4j.GraphDatabaseService()
query_string = "START beginning=node(1), end=node(4) \
MATCH p = shortestPath(beginning-[*..500]-end) \
RETURN p"
result = neo4j.CypherQuery(graph_db, query_string).execute()
for r in result:
print type(r) # r is a py2neo.util.Record object
print type(r.p) # p is a py2neo.neo4j.Path object
Ok, I figured it out. I used the tutorial [here]( based on #nigel-small 's answer.
from py2neo import cypher
session = cypher.Session("http://localhost:7474")
tx = session.create_transaction()
tx.append("START beginning=node(3), end=node(16) MATCH p = shortestPath(beginning-[*..500]-end) RETURN p")
tx.execute()
which returned:
[[Record(columns=(u'p',), values=(Path(Node('http://localhost:7474/db/data/node/3'), ('threads', {}), Node('http://localhost:7474/db/data/node/1'), ('threads', {}), Node('http://localhost:7474/db/data/node/2'), ('threads', {}), Node('http://localhost:7474/db/data/node/16')),))]]
From here, I expect I'll inflate each of the values back to my neomodel objects and into django for easier manipulation. Will post that code as I get there.
The error message you provide is specific to neomodel and looks to have been raised as there is not yet any support for inflating py2neo Path objects in neomodel.
This should however work fine in raw py2neo as paths are fully supported, so it may be worth trying that again. Py2neo certainly wouldn't raise an error from within the neomodel code. I've just tried a shortestPath query myself and it returns a value as expected.