Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
03-28-2022 10:23 AM
Hello neo4j people,
this is quite probably a newbie question but I haven't found anything on the subject here/internet.
(With map I mean object (js), dictionary, key/value-pair)
Setup DB: CREATE (n:Node {prop1: 'val1', prop2: 'val2'})
.
When one wants a specific subset of the props one can obviously do something like:
UNWIND ['prop1', 'prop2', 'prop3'] as k, MATCH (n:Note) RETURN [k, n[k]]
This shall give the result: [['prop1', 'val1'], ['prop2', 'val2'], ['prop3', null]]
As maps and map accessors are obviously supported I was wondering whether it's possible to also get this result back in a map, so : {prop1: 'val1', prop2: 'val2', prop3: null}
.
As it's possible to do something like WITH {a: 'hello'} as map1 RETURN map1
which is {a: 'hello'}
I tried to do the following WITH {} as result UNWIND ['prop1', 'prop2', 'prop3'] as k, MATCH (n:Note) SET result[k] = n[k] RETURN k
Unfortunately this doesn't work as SET only works on nodes. I also tried setProperty of apoc: apoc.create.setProperty - APOC Documentation but this also only works on nodes. So I have two questions:
Solved! Go to Solution.
03-28-2022 04:10 PM
If you want a map of a defined set of a node's properties, then the following works. It relies on the APOC library. I was not able to figure out getting the data as a map using pure cypher. I could not find a method to dynamically add elements to a map. You can build a map if you know the keys up front, such as:
return {name: n.name, city: n.city}
query using APOC:
with ['prop1', 'prop2', 'prop3'] as keys
match(n) where id(n) = 102
with keys, properties(n) as props
unwind keys as key
with collect(key) as keys, collect(props[key]) as values
return apoc.map.fromLists(keys, values) as map
hope is is what you wanted.
03-28-2022 12:38 PM
You can use the 'properties' method on a node to get a map of its properties. The props value in the query below will be a map of all node n's properties.
match(n)
return properties(n) as props
If you want a subset of the properties, you can use the map projection syntax. For instance, if you want only properties prop1, prop2, and prop3, you can use the following syntax:
match(n)
with properties(n) as props
return props{ .prop1, .prop2, .prop3}
You can also add your own key/values to the map. Say you want to add a key 'name' and its value is in a variable 'fname', then you can do something like:
match(n)
with properties(n) as props
return props{ .prop1, .prop2, .prop3, name: fname}
if you want to add a variable, such as 'name', and use its name as the key, you can do the following:
match(n)
with properties(n) as props
return props{ .prop1, .prop2, .prop3, name}
If you want all the key/value pairs of a map and add a new key/value, you could do the following:
match(n)
with properties(n) as props
return props{ .*, name}
You can also build a map from scratch as follows:
match(n)
return {id: id(n), key: n.key, name: n.name}
03-28-2022 03:01 PM
Hello @glilienfield, thank you for your answer. Unfortunately although your answers perfectly satisfy my given questions, they don't satisfy my motivation for this post. But that is my fault as I didn't write my first questions precise enough. My motivation was that given I have a list of unknown entries which represent some keys of the node props how do I retrieve those props:
So given: :param unknownkeys => ['prop1', 'prop3']
And instead of match (n:Node) unwind $unknownkeys as k return [k, n[k]]
which works but returns a list, something like match (n:Node) unwind $unknownkeys as k return { [k]: n[k] }
(which does not work in cypher). Also somethink like this match (n:Node) unwind $unknownkeys as k return properties(n){[k]}
does also not work. So really the question is how to get the props as a map although the keys are not known or simply shall not directly specified in the query?
I can also make a new post of this if that is better.
03-28-2022 04:10 PM
If you want a map of a defined set of a node's properties, then the following works. It relies on the APOC library. I was not able to figure out getting the data as a map using pure cypher. I could not find a method to dynamically add elements to a map. You can build a map if you know the keys up front, such as:
return {name: n.name, city: n.city}
query using APOC:
with ['prop1', 'prop2', 'prop3'] as keys
match(n) where id(n) = 102
with keys, properties(n) as props
unwind keys as key
with collect(key) as keys, collect(props[key]) as values
return apoc.map.fromLists(keys, values) as map
hope is is what you wanted.
All the sessions of the conference are now available online