Redisgraph: Support for maps outside of node and relation patterns

Created on 21 Feb 2020  路  7Comments  路  Source: RedisGraph/RedisGraph

I have an array of object with unknown properties, i'd like to insert them as nodes

array = [{ foo: 'bar' }, { a: 1, b: 2 }, ...]
query = `UNWIND $array AS properties CREATE (:label properties)`

I was thinking of trying to implement an AST parser inside my JS driver but as it seems complex, i'm first asking if there is any plan to support this functionality in RedisGraph.

related to #784

Thanks

3d enhancement

Most helpful comment

Hi @Sceat, unfortunately not yet, we're currently focusing on different areas of the project.
that said we'll try to accommodate this datatype as we understand its importance.

All 7 comments

Hi @Sceat ,

Full support for map objects is definitely on our roadmap, but we don't have an ETA on it yet - it's not a short-term goal.

The Cypher to accomplish what you're describing would actually look like this:
UNWIND $array AS properties CREATE (a:label) SET a = properties

Would writing a query like this let you solve the problem in-driver as you did with SET += in #916 ?

Hi,
I don't think i can because UNWIND make properties out of my scope, i would need some way to retrieve an index to know if it's actually array[0] or array[1] .

My usecase is like

WITH $sessions as userSessions
UNWIND userSessions AS userSession
MERGE (user)-[:HAS_SESSION]->(mergedSession:Session { hash: userSession.hash })
SET mergedSession += userSession

I'm going to study the AST to see if i can support that kind of stuff in the driver (i don't know anything in C)

Hm, interesting! It sounds to me like using the ON MATCH SET and ON CREATE SET directives for MERGE (described a bit here) might be of some help to you, but those still don't address the current lack of map support.

We use libcypher-parser to build our ASTs - among its perks are great support for user introspection. For example, you can print a query's AST to the command line like so:

$ cd deps/libcypher-parser/linter/
$ echo "WITH \$sessions as userSessions UNWIND userSessions AS userSession MERGE (user)-[:HAS_SESSION]->(mergedSession:Session { hash: userSession.hash
}) SET mergedSession += userSession" | ./src/cypher-lint -a
 @0    0..179  statement                 body=@1
 @1    0..179  > query                   clauses=[@2, @6, @9, @23]
 @2    0..31   > > WITH                  projections=[@3]
 @3    5..31   > > > projection          expression=@4, alias=@5
 @4    5..14   > > > > parameter         $`sessions`
 @5   18..30   > > > > identifier        `userSessions`
 @6   31..66   > > UNWIND                expression=@7, alias=@8
 @7   38..50   > > > identifier          `userSessions`
 @8   54..65   > > > identifier          `userSession`
 @9   66..146  > > MERGE                 path=@10
@10   72..145  > > > pattern path        (@11)-[@13]-(@15)
@11   72..78   > > > > node pattern      (@12)
@12   73..77   > > > > > identifier      `user`
@13   78..95   > > > > rel pattern       -[:@14]->
@14   80..92   > > > > > rel type        :`HAS_SESSION`
@15   95..145  > > > > node pattern      (@16:@17 {@18})
@16   96..109  > > > > > identifier      `mergedSession`
@17  109..117  > > > > > label           :`Session`
@18  118..144  > > > > > map             {@19:@20}
@19  120..124  > > > > > > prop name     `hash`
@20  126..143  > > > > > > property      @21.@22
@21  126..137  > > > > > > > identifier  `userSession`
@22  138..142  > > > > > > > prop name   `hash`
@23  146..179  > > SET                   items=[@24]
@24  150..179  > > > merge properties    @25 += @26
@25  150..163  > > > > identifier        `mergedSession`
@26  167..178  > > > > identifier        `userSession`

This might be of some help to you! (Note that I had to escape the $ character with a backslash.)

Tried a bit to playaround with the AST but in fact i don't see a viable solution, i can reconstruct the query from a modified AST to a format that redisgraph support but that's the same thing as just swiping UNWIND for a loop with actual values

UNWIND $array AS properties CREATE (a:label) SET a = properties

would become something like

CREATE (:label { $array[0] })
CREATE (:label { $array[1] })
CREATE (:label { $array[2] })
CREATE (:label { $array[3] })

i'll manually do that instead of using the UNWIND keyword and wait for redisgraph support.
+= support would also be dope!

coming for news @jeffreylovitz @swilly22 any plan in sight to support maps ?

Hi @Sceat, unfortunately not yet, we're currently focusing on different areas of the project.
that said we'll try to accommodate this datatype as we understand its importance.

that said we'll try to accommodate this datatype as we understand its importance.

MATCH (actor:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(movies) 
WITH actor, collect(properties(movies)) AS moviesList
RETURN {
         actor:  {name: actor.name, born: actor.born},
         movies: moviesList
       }

A nice use is taking a tree graph (ie where the root is an actor named Tom Hanks) and returning that tree in JSON format.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Talha-B picture Talha-B  路  5Comments

Sceat picture Sceat  路  5Comments

sidenAlex picture sidenAlex  路  3Comments

K-Jo picture K-Jo  路  9Comments

WitchsCat picture WitchsCat  路  10Comments