cypher-query-language-builder
Fork of cypher-tagged-templates
- NPM: https://www.npmjs.com/package/cypher-query-language-builder
- Github: https://github.com/johnsonjo4531/cypher-query-language-builder#readme
Table of Contents:
What?
A tiny helper for securely writing and running Cypher queries using Javascript tagged templates. This query builder is designed to help be as close to cypher as possible while providing convenience methods that help you write your queries through the default driver without the added pain.
Why?
I found the default driver's parameterization to be a little akward this is where template strings come in handy.
I also found the driver hard to use when trying to insert objects from JavaScript, so the cql.fromProps()
method
was something designed to help alleviate that pain. Other query builders seemed to take away from the simpleness of the
cypher query language by almost completely abstracting it away into methods. One goal of this project is to keep things
as close to looking like the cypher query language as possible.
How?
Installation
npm install --save cypher-query-language-builder
Basic example
It supports variables interpolation, automatically using the Neo4j driver to escape values.
The return value of the query is an array of records, after calling the toObject
method on them.
const neo4j = v1;const Cypher = default; const driver = neo4j;const cql = driver query; const email = "anna@example.com";const query = cql` MATCH (user:User {email: }) RETURN user`; const result = query; // at some point// driver.close()
Node insertion
You can create a node with a given variable name
, some given labels
, and a given properties
object that is whitelisted through propsWhitelist
.
// cql setup const annaNode = cql; const bananaNode = cql; const query = cql`CREATE CREATE RETURN anna, annabananna`; query ;
Setting
Setting is how you update certain properties in Neo4j. In order to quickly write a setter from an object and whitelist you can use
the cql.setters()
method. In the below we Match any existing node's with Anna's email or create it if it's not there by using a MERGE clause and set that node with her name and address using a SET clause with .setters()
.
// cql setup const anna = email: "anna@example.com" name: "anna" address: "123 Washington Blvd."; const annaNode = cql; const annaSetters = cql; const query = cql`MERGE SET RETURN anna`; query ;
Relationships
You can create a relationship with a given variable name
, some given labels
, and a given properties
object that is whitelisted through propsWhitelist
.
// cql setup const annaNode = cql; const friend = cql; const bananaNode = cql; const query = cql`CREATE CREATE CREATE (anna) (annabananna) RETURN anna, annabananna, fr`; query ;
Enable automatic integers parsing
You can configure the helper to automatically convert Neo4j integers to native Javascript, avoiding having to deal with that yourself.
// ... const driver = neo4j; const cql = driver parseIntegers: truequery; // ...
Override configuration options when running a query
// ...const cql = driver query;const query = cql` MATCH (user:User {status: "active"}) RETURN user`; const result = await query;// ...
Nested queries
You can also nest subqueries as variables.
// ...setup const email = "anna@example.com";const selectDb = cql`MATCH (neo:Database {name: "Neo4j"})`;const selectPerson = cql`MATCH (anna:Person {email: })`;const createFriend = cql` CREATE (anna) -[:FRIEND]->(:Person:Expert {name:"Amanda"}) -[:WORKED_WITH]->(neo)`; const mainQuery = cql` `; const result = mainQuery;
Array input
You can add arrays of any valid interpolation value and they will be concatenated together in your query.
// ...setup const anna = email: "anna@example.com" name: "anna";const selectPerson = cql`MATCH (anna:Person {}) RETURN anna`;/** * The Query string should be: * MATCH (anna:Person {email: {p_0_1}, name: {p_0_3}}) * RETURN anna * * and the Paramaters should be: * { * p_0_1: "anna@example.com", * p_0_3: "anna" * } */ const result = mainQuery;
Insert Whitelisted Object
You can insert whitelisted properties and values from an object using the cql.fromProps(propsWhitelist, object)
property. Where propsWhitelist
is an array of strings representing properties to whitelist on the object
This is the same query as above using cql.fromProps()
.
// ...setup const anna = email: "anna@example.com" name: "anna" other: "H4x0r User input";const whitelistedProps = "email" "name" "nonExistentProp";const selectPerson = cql`MATCH (anna:Person {}) RETURN anna`;/** * The Query string should be: * MATCH (anna:Person {email: {p_0_1}, name: {p_0_3}}) * RETURN anna * * and the Paramaters should be: * { * p_0_1: "anna@example.com", * p_0_3: "anna" * } */ const result = mainQuery;
Manual queries
Instead of directly runing the queries, you can export them as a string and a parameters object so you can execute them yourself (E.g. execute multiple queries as part of a transaction).
// ...setup const email = "anna@example.com";const status = "active";const findUser = cql` MATCH (user:User {email: }) WHERE status = RETURN user`; const query params = findUser; /*query = 'MATCH (user:User {email: {p_0}}) WHERE status = {p_1} RETURN user'params = { p_0: 'anna@example.com', p_1: 'active'}*/
Using with Typescript
An example of using Typescript's generic types
// ...;; ;// result is an array of {user: IUser}// ...
API
index.d.ts
;;;;;
CypherHelper.d.ts
;;;declare ;
CypherQuery.d.ts
;
CypherRawText.d.ts
Errors.d.ts
declare
Interfaces.d.ts
;
More Examples
See the tests in ./src/__tests__
for more examples