cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Pluck property of parameters

Hello,

I am trying to "pluck" i.e. retrieve from each item of an array parameter.
Given a users and posts parameters:

{
  "users" : [ {
    "name" : "Andy",
    "position" : "Developer"
  }, {
    "name" : "Michael",
    "position" : "Developer"
  } ],
  "posts" : [ {
    "tag" : "lifestyle"
  }, {
    "tag" : "science"
  } ]
}

To try something of the sort:

MATCH (u:User),
(p:Post)
WHERE u.name IN pluck($users.name),
p.tag IN pluck($posts.tag)
RETURN u, p;

I know that this is possible for a parameter of type list, as shown here.

An option would be to UNWIND as shown here.
But in this particular case this is not convenient since it would result in nested UNWINDs.
To avoid nesting, if we consider FOREACH another challenge would surface related to variable context.

All in all, as you can see it is not straight forward at all to achieve this relatively simple operation using neither UNWIND nor FOREACH.

Please note that the above CYPHER query has been stripped down to the scope of this question.

Is there a way to do this out of the box? Or available in APOC?

Thank you.

Environment:

  • Neo4j v4.2.3
  • Golang driver
1 REPLY 1

Hi again,

First, i would like to add an update on the above comment regarding nested UNWINDs, that this could be avoided by resetting cardinality.

I wonder how are parameters dealt with, are these considered Collections or Maps?

For instance creating the following param:
:param posts => [{tag: "lifestyle"}, {tag: "science"}]
And calling RETURN $posts[0]["tag"]; returns lifestyle. So apparently it is dealt with as a Collection.

I found APOC Collection Functions but i couldn't find the functionality I am looking for, which is to get all tag values.

While writing this reply, I also found APOC Map Functions; to confirm that the param is a Collection rather than a Map I tried RETURN apoc.map.mget($posts,"tag") but got the following error:

Type mismatch: expected List<String> but was String (line 1, column 29 (offset: 28))
"RETURN apoc.map.mget($posts,"tag")"
                             ^

That leaves it clear that $posts is a Collection, so unfortunately I won't be able to use apoc.map.mget().

Trying to find a way around this I decided to try and define a JSON object rather than a JSON array param:

:param input => {users: [{name: "Andy", position: "Developer"}, {name: "Michael", position: "Developer"}], posts: [{tag: "lifestyle"}, {tag: "science"}]}

Despite input being a valid JSON structure the above return a syntax error:

Invalid input 'r' (line 1, column 4 (offset: 3))
"users: [{name: "Andy", position: "Developer"}, {name: "Michael", position: "Developer"}], posts: [{tag: "lifestyle"}, {tag: "science"}]"
    ^

To resume, I am still trying to achieve a "pluck" like behaviour on a Collection type param of nested objects. Any alternatives to pass a Map would still work.

Thank you.