3

I have a query like this:

unwind {data} as row with row MERGE (p:Book{guid:row.bookGuid}) set p.name=row.name, p:Science

I want to pass the label 'Science' as a parameter as this label is not same for all the rows which I am passing in {data}.

I tried below query, but this is throwing syntax error.

with parameter like: { guid:1, name:"testName1",label1:"Histroy"}

unwind {data} as row with row MERGE (p:Book{guid:row.bookGuid}) set p.name=row.name, p:row.label1

Any workaround?

Thanks

Community
  • 1
  • 1
Krishna Shetty
  • 1,361
  • 4
  • 18
  • 39
  • Just came across this - http://stackoverflow.com/questions/24274364/in-neo4j-how-to-set-the-label-as-a-parameter-in-a-cypher-query-from-java --Not yet supported? – Krishna Shetty Nov 28 '14 at 13:15
  • "Parameters can not be used as for property names, relationship types and labels, since these patterns are part of the query structure that is compiled into a query plan." http://neo4j.com/docs/2.1.6/cypher-parameters.html – Krishna Shetty Nov 28 '14 at 13:39
  • Not yet but hopefully soon. – Michael Hunger Nov 30 '14 at 04:24

3 Answers3

2

You can use APOC apoc.create.addLabels():

UNWIND {data} as row WITH row
MERGE (p:Book{guid:row.bookGuid})
SET p.name=row.name
CALL apoc.create.addLabels(id(p), [row.label1])

Another example: Using Cypher and APOC to move a property value to a label

1

Yeh it's not supported yet. If you want to make it work you have to do a bit of a hack using FOREACH which you'll have to do for each type of label:

unwind {data} as row with row 
FOREACH(ignoreMe IN CASE WHEN row.label = "Science" THEN [1] ELSE [] END |
    MERGE (p:Book:Science{guid:row.bookGuid}) 
    set p.name=row.name
)

FOREACH(ignoreMe IN CASE WHEN row.label = "Math" THEN [1] ELSE [] END |
    MERGE (p:Book:Math{guid:row.bookGuid}) 
    set p.name=row.name
)

And so on...

Mark Needham
  • 2,098
  • 17
  • 19
1

I guess that you could structure your data differently:

(:Book {guid, name})-[:HAS_LABEL]->(:Label {name})

In this way you could use the label name as parameter in CREATE or MATCH queries. Your original query would be:

UNWIND {data} as row WITH row 
MERGE (p:Book {guid: row.guid})
MERGE (l:Label {name: row.label})
CREATE UNIQUE p-[:HAS_LABEL]->l
SET p.name = row.name
zaboco
  • 2,798
  • 1
  • 20
  • 16
  • Yes but that would defeat the advantage of using the Neo4j labels as a convenient and fast way of accessing your data if you always have to go through the category node. In some cases this is useful though (hierarchies of labels). – Michael Hunger Nov 30 '14 at 04:23
  • Yes, it would be slower like this (although indexing Labels by name should make it fast enough), but I think that, in this case, Book label is not meant to be a node label. IMO, neo4j node labels should be like OOP classes, and Book label is more like a field. – zaboco Dec 01 '14 at 12:06