6

I'm working on a project in flask and neo4j. I need to retrieve all the properties from a node as dict. Something like this

{'gender': 'male', 'password': '$2a$12$fd5KtsMjZHz26goBGcF3/.gZhZUP/6YAP7lRQ8Kf6eB5m69EhB5lS', 'email': 'xyz@gmail.com', 'age': '50', 'country': 'US', 'username': 'xyz'}

I stumbled across this question while searching for answer

How can I return all properties for a node using Cypher? where it is sugegsted that it is possible to return properties names as keys.

In version 2.3.0, it is possible return values as well For e.g I have node with these properties

username xyz

email xyz@gmail.com

age 50

gender male

password $2a$12$fd5KtsMjZHz26goBGcF3/.gZhZUP/6YAP7lRQ8Kf6eB5m69EhB5lS

If I return n with query below

>>>for record in graph.cypher.execute("MATCH (n:User) WHERE n.username='xyz' RETURN n"):

...         print(record[0])

Results are returned in a row with this in front (n11:User, so I cannot use this result in jinja template directly without further processing


(n11:User {age:"50",country:"US",email:"xyz@gmail.com",gender:"male",password:"$2a$12$fd5KtsMjZHz26goBGcF3/.gZhZUP/6YAP7lRQ8Kf6eB5m69EhB5lS",username:"xyz"})

If I use the query below

>>>for record in graph.cypher.execute("MATCH (n:User) WHERE n.username='xyz'
RETURN EXTRACT(key IN keys(n) | {value: n[key], key:key})"):

...         print(record[0])

I get these results.

[{'value': 'xyz@gmail.com', 'key': 'email'}, {'value': '50', 'key': 'age'}, {'value': 'US', 'key': 'country'}, {'value': 'xyz', 'key': 'username'}, {'value': '$2a$12$fd5KtsMjZHz26goBGcF3/.gZhZUP/6YAP7lRQ8Kf6eB5m69EhB5lS', 'key': 'password'}, {'value': 'male', 'key': 'gender'}]

Problem with this query is that, it doesn't really return key value tuples but instead append key and value labels in front of keys and values. It is not possible to use the output as it without further processing.
Or is there another way to run the query to get results as dict ?

Also, from idea box for Neo4j

https://trello.com/c/FciCdgWl/7-cypher-property-container-functions

It seems it could be possible to do these queries

Possible functions:

MATCH n RETURN keys(n) Returns the collection of property keys.

MATCH n RETURN values(n) Returns the collection of property values.

MATCH n RETURN entries(n) Returns a collection of key/value pairs.

But I can only run - MATCH n RETURN keys(n)

For rest I get invalid syntax error. Rest of the function are not implemented ?

Community
  • 1
  • 1
jas
  • 1,539
  • 5
  • 17
  • 30

2 Answers2

8

If you just do RETURN n then the node properties are returned as a map.

See: http://neo4j.com/docs/stable/rest-api-transactional.html#rest-api-execute-multiple-statements

This one controls you programmatically filter the properties that you want to return:

MATCH (n) WHERE id(n)=#
RETURN EXTRACT(key IN keys(n) | {key: key, value: n[key]}) 

Otherwise if you know which ones to return you spell them out: RETURN n.name, n.age.

Michael Hunger
  • 41,339
  • 3
  • 57
  • 80
  • sorry, I didn't realize I didn't explain the purpose why I want results in a dict. I have edited the question to reflect that and I have also put results from Return n. Couldn't have added all in comment. So, using Return n doesn't solve my problem. And getting indiviual properties with RETURN n.name, n.age would be inefficient. Right now, I just filter values and keys in different list from the output and then combine the two list together into the dict that can be fed into jinja template. But, I was wondering if all that post-processing can be saved – jas Jan 08 '16 at 04:07
  • 1
    If you `RETURN n` as Michael suggests, you can then use `.properties` from the `Node` that is returned to give you the entire set of properties as a dictionary. For example: `print(record[0].properties)`. – Nigel Small Jan 08 '16 at 21:29
  • 1
    @NigelSmall , is it possible to read individual property from a node object? for e.g print(record[0].age). If I try that I get this error Node' object has no attribute 'age'? Or the only option to do as Michael suggested i.e RETURN n.age AS age") and then print(record.age) – jas Jan 14 '16 at 00:28
1

According to the cypher documentation for neo4j 3.5, there is an "all-properties selector" for maps. You can also use the properties function mentioned here:

MATCH (node)
RETURN
  id(node) AS neo4j_id,
  node {.*} AS node_properties_1,
  properties(node) AS node_properties_2
LIMIT 2
Daniel Himmelstein
  • 1,759
  • 1
  • 21
  • 26