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.

How to Pass Input Value into Cypher Query?

keithave
Node Clone

Please fwd this to a better category if necessary. I'm running nodejs and from an ejs page, I'm trying to send an input value into a Cypher query that will result in a vis.js display of a graph. Note : All javascript actions are taking place on the ejs page, there is no server contact in this case.

I can render the Neo4j graph no problem when running the query without any attempts of adding the input value.

This Works Clicking this button...

    <input type="submit" onclick="displayGraph()" value='Display Graph' class="button">

...runs this function which includes the Cypher query (no input in this query) and renders the Neo4j graph as expected.

    function displayGraph() {
        // Create the authorization header for the ajax request.
        AUTHORIZATION = "Basic " + btoa("abc"+":"+"123");

        // Post Cypher query to return node and relations and return results as graph.
        restPost({
            "statements": [
                {
                    "statement": `MATCH (bry:Brewery)-[r:BREWS]->(b:Beer {name: 'Pliny the Elder'})-[r2:IS_A]->(bt:BeerType)
                                    Optional Match (b)-[r3:BREWED_WITH]->(h:Hop) 
                                    Return bry,r,b,r2,bt,r3,h`,
                    "resultDataContents": ["graph"]
                }
            ]
        }).done(function (data) {
            
            // Parse results and convert it to vis.js compatible data.
            var graphData = parseGraphResultData(data);
            var nodes = convertNodes(graphData.nodes);
            var edges = convertEdges(graphData.edges);
            var visData = {
                nodes: nodes,
                edges: edges
            };
            displayVisJsData(visData);
        });
    }

This Doesn't Work If I use an input field to capture the name of a beer...

<label>
    Beer Name:<input name="inputbeer" id="inputbeer" type="text">
</label>

...and then click the same button...

<input type="submit" onclick="displayGraph()" value='Display Graph' class="button">

...I run the similar function, but have tried a number of variations on passing the input value into the Cypher query like this (everything is the same as the function seen above, just amending the Cypher query)...

MATCH (bry:Brewery)-[r:BREWS]->(b:Beer {name: '$inputbeer'})-[r2:IS_A]->(bt:BeerType)
                                    Optional Match (b)-[r3:BREWED_WITH]->(h:Hop) 
                                    Return bry,r,b,r2,bt,r3,h

...this and other variations don't work. I've tried {name: {inputbeer}}... {name: {$inputbeer}}... {name: $inputbeer}... so many possibilities. I'm guessing it's a simple format issue, but I'm at a loss.

Thank you for any help!

2 REPLIES 2

keithave
Node Clone

After a little more experimenting, I am able to pass the input value to my Cypher query.

2 modifications were necessary:

1 I needed to add a var inside my function that would capture the value of the input:

var inputthebeer = document.getElementById("inputbeer").value;

2 I had to update my Cypher query to allow me to insert that var:

`MATCH (bry:Brewery)-[r:BREWS]->(b:Beer {name: '`+inputthebeer+`'})-[r2:IS_A]->(bt:BeerType) Optional Match (b)-[r3:BREWED_WITH]->(h:Hop) Return bry,r,b,r2,bt,r3,h` 

Usually I would say, Hey! Read this amazing example on the JavaScript Neo4j Driver manuel, but to be honest, unlike the cypher manuel, the JavaScript driver manuel sucks ( the HTML version at least )

I didn't find any good example in it, but I got your answer.

var inputthebeer = document.getElementById("inputbeer").value;

This part is OK you need your inputthebeer variable
You need to write exactly $inputthebeer in your query nothing else, no '$inputthebeer'
You need to create a map { beer: inputthebeer } and write it as the second argument of your javascript neo4j driver function, the one who do the query itself. Like session.run.

Example:

var request = USE suivi MERGE (p:Processus:${user} {nom:toLower($nom)}) ON CREATE SET p.uuid = randomUUID(), p.creation = timestamp() RETURN p.uuid AS uuid, p.creation AS creation;
session.run(request, {nom: nom} )

Backtick are present at the beginning and the end of the query string, the website doesn't show it I don't known why.

Here
$nom in the query is a cypher parameter you can use them on property value
YOU HAVE TO add the parameters in the map as the second parameter of the session.run function. You can see it above. Cypher will perform better with properties values as parameter.

${user} is a simple text replacement, it's available with the use of backtick only .
orange = 'Orange'
size = 5

So this : MATCH (:${orange} {size: $size})
Will become this in Cypher: MATCH(:Orange {size: $size})

Cypher will use internally the parameter pass as the second argument ini the .run function to work with the $size as a part of the query unlike orange who is just a text replacement.

You can NOT use parameters for labels, relationships types or property names.