2

I am building an app that give users the ability to construct there own graphs. I have been using parameters for all queries and creates. But when I want to give users the ability to create a node where they can also Label it anything they want(respecting neo4j restrictions on empty string labels). How would I parameterize this type of transaction?

I tried this:

.CREATE("(a:{dynamicLabel})").WithParams(new {dynamicLabel = dlabel})... 

But this yields a syntax error with neo. I am tempted to concatenate, but am worried that this may expose an injection risk to my application.

I am tempted to build up my-own class that reads the intended string and rejects any type of neo syntax, but this would limit my users a bit and I would rather not.

Govind Singh
  • 15,282
  • 14
  • 72
  • 106
abarraford
  • 655
  • 2
  • 7
  • 23

3 Answers3

1

There is an open neo4j issue 4334, which is a feature request for adding the ability to parameterize labels during CREATE.So, this is not yet possible.

That issue contains a comment that suggests generating CREATE statements with hardcoded labels, which will work. It is, unfortunately, not as performant as using parameters (should it ever be supported in this case).

cybersam
  • 63,203
  • 6
  • 53
  • 76
  • I like the thought of creating a property hardcoded as "Label" with a value as the intended label, yet this comes with some downsides. I think I will go ahead and do two things. Restrict users label lengths, in characters to a small finite number (20 Characters) for now and create rules for user generated labels that does not allow any labels that contain neo cypher keywords. Then if the feature is added to neo, I can swap it out and remove the rules. – abarraford Aug 26 '15 at 00:20
1

I searched like hell and finally found it out. you can do it like that:

// create or update nodes with dynamic label from import data
WITH "file:///query.json" AS url
call apoc.load.json(url) YIELD value as u
UNWIND u.cis as ci
CALL apoc.merge.node([ ci.label ], {Id:ci.Id}, {}, {}) YIELD node
RETURN node;

The JSON looks like that:

{
   "cis": [
     {
       "label": "Computer",
       "Id": "1"
     },
     {
       "label": "Service",
       "Id": "2"
     },
     {
       "label": "Person",
       "Id": "3"
     }
   ],
   "relations": [
     {
       "end1Id": "1",
       "Id": "4",
       "end2Id": "2",
       "label": "USES"
     },
     {
       "end1Id": "3",
       "Id": "5",
       "end2Id": "1",
       "label": "MANAGED_BY"
     }
   ]
 }
Cellcore
  • 824
  • 6
  • 8
0

If you are using a Java client, then you can do it like this.

        Node node = GraphDatabaseService.createNode();

        Label label = new Label() {                 
            @Override
            public String name() {
                return dynamicLabelVal;
            }
        };

        node.addLabel(label);

You can then have a LabelCache which will avoid Label object creation for every node.

Atul Soman
  • 4,612
  • 4
  • 30
  • 45