Options
All
  • Public
  • Public/Protected
  • All
Menu

Cypher Query Builder

Build Status Coverage Status Commitizen friendly

Become a patreon

A flexible and intuitive query builder for Neo4j and Cypher. Write queries in Javascript just as you would write them in Cypher.

  • Easy to use fluent interface
  • Support for streaming records using observables
  • Full Typescript declarations included in package
let results = await db.matchNode('user', 'User', { active: true })
  .where({ 'user.age': greaterThan(18) })
  .with('user')
  .create([
    cypher.node('user', ''),
    cypher.relation('out', '', 'HasVehicle'),
    cypher.node('vehicle', 'Vehicle', { colour: 'red' })
  ])
  .ret(['user', 'vehicle'])
  .run();

// Results:
// [{
//   user: {
//     identity: 1234,
//     labels: [ 'User' ],
//     properties: { ... },
//   },
//   vehicle: {
//     identity: 4321,
//     labels: [ 'Vehicle' ],
//     properties: { ... },
//   },
// }]

Contents

Quick start

Installation

npm install --save cypher-query-builder

or

yarn add cypher-query-builder

Importing

CommonJS/Node

const cypher = require('cypher-query-builder');
// cypher.Connection
// cypher.greaterThan
// ....

ES6

import { Connection, greaterThan } from 'cypher-query-builder';

Connecting

const cypher = require('cypher-query-builder');

// Make sure to include the protocol in the hostname
let db = new cypher.Connection('bolt://localhost', {
  username: 'root',
  password: 'password',
});

Cypher query builder uses the official Neo4j Nodejs driver over the bolt protocol in the background so you can pass any values into connection that are accepted by that driver.

Querying

ES6

db.matchNode('projects', 'Project')
  .return('projects')
  .run()
  .then(function (results) {
    // Do something with results
  });

ES2017

const results = await db.matchNode('projects', 'Project')
  .return('projects')
  .run();

run will execute the query and return a promise. The results are in the standardish Neo4j form an array of records:

const results = [
  {
    projects: {
      // Internal Neo4j node id, don't rely on this to stay constant.
      identity: 1,

      // All labels attached to the node
      labels: [ 'Project' ],

      // Actual properties of the node.
      // Note that Neo4j numbers will automatically be converted to
      // Javascript numbers. This may cause issues because Neo4j can
      // store larger numbers than can be represented in Javascript.
      // This behaviour is currently in consideration and may change
      // in the future.
      properties: { name: 'Project 1' },
    },
  },
  // ...
]

You can also use the stream method to download the results as an observable.

const results = db.matchNode('project', 'Project')
  .ret('project')
  .stream();

results.subscribe(row => console.log(row.project.properties.name));

Processing

To extract the results, you can use ES5 array methods or a library like lodash:

// Get all the project nodes (including their id, labels and properties).
let projects = results.map(row => row.projects);

// Get just the properties of the nodes
let projectProps = results.map(row => row.projects.properties);

Documentation

All the reference documentation can be found here. However, the two most useful pages are probably:

  • The Connection class, for details on creating and using a connection.
  • The Query class, for details on all the available clauses, and building and running queries.

Contributing

Please feel free to submit any bugs or questions you may have in an issue. I'm very open to discussing suggestions or new ideas so don't hesitate to reach out.

Maintaining the library does take some time out of my schedule so if you'd like to show your appreciation please consider donating. Even the smallest amount is really encouraging.

Become a patreon

License

MIT License

Copyright (c) 2018 James Ferguson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Index

Type aliases

Comparator

Comparator: function

Type declaration

    • (params: ParameterBag, name: string): string
    • Parameters

      • params: ParameterBag
      • name: string

      Returns string

ConnectionOptions

ConnectionOptions: Partial<FullConnectionOptions>

DriverConstructor

DriverConstructor: driver

Variables

Let connections

connections: Connection[] = []

Const isTrueFunction

isTrueFunction: function = isFunction

Type declaration

    • (value: any): value is Function
    • Parameters

      • value: any

      Returns value is Function

Functions

and

  • and(conditions: AndConditions): WhereAnd
  • AND operator to use in where clauses. This is the default operator when using conditions so you will probably never need to use this unless you'd like to make it explicit.

    query.where(and({
      'person.name': 'Steve',
      'person.age': greaterThan(18),
    }));
    // WHERE person.name = 'Steve' AND person.age > 18

    Note that this method only accepts a dictionary of conditions.

    Parameters

    • conditions: AndConditions

    Returns WhereAnd

between

  • between(lower: any, upper: any, lowerInclusive?: boolean, upperInclusive?: boolean, variables?: undefined | false | true): Comparator
  • Between comparator for use in where clauses. This comparator uses Neo4j's shortcut comparison syntax: 18 <= age <= 65.

    The lower and upper are the bounds of the comparison. You can use lowerInclusive and upperInclusive to control whether it uses <= or < for the comparison. They both default to true.

    If you pass only lowerInclusive then it will use that value for both.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ age: between(18, 65) })
    // WHERE age >= 18 AND age <= 65
    
    query.where({ age: between(18, 65, false) })
    // WHERE age > 18 < AND age < 65
    
    query.where({ age: between(18, 65, true, false) })
    // WHERE age >= 18 AND age < 65
    
    query.where({ age: between('lowerBound', 'upperBound', true, false, true) })
    // WHERE age >= lowerBound AND age < upperBound

    Parameters

    • lower: any
    • upper: any
    • Default value lowerInclusive: boolean = true
    • Default value upperInclusive: boolean = lowerInclusive
    • Optional variables: undefined | false | true

    Returns Comparator

compare

  • compare(operator: string, value: any, variable?: undefined | false | true, paramName?: undefined | string): Comparator

contains

  • contains(value: string, variable?: undefined | false | true): function
  • Contains comparator for use in where clauses.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ name: contains('steve') })
    // WHERE name CONTAINS 'steve'
    
    query.where({ name: contains('clientName', true) })
    // WHERE name CONTAINS clientName

    Parameters

    • value: string
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

endsWith

  • endsWith(value: string, variable?: undefined | false | true): function
  • Ends with comparator for use in where clauses.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ name: endsWith('steve') })
    // WHERE name ENDS WITH 'steve'
    
    query.where({ name: endsWith('clientName', true) })
    // WHERE name ENDS WITH clientName

    Parameters

    • value: string
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

equals

  • equals(value: any, variable?: undefined | false | true): function
  • Equals comparator for use in where clauses. This is the default so you will probably never need to use this.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ age: equals(18) })
    // WHERE age = 18
    
    query.where({ name: equals('clientName', true) })
    // WHERE age = clientName

    Parameters

    • value: any
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

exists

  • Exists comparator for use in where clauses. Note that this comparator does not accept any arguments

    query.where({ person: exists() })
    // WHERE exists(person)

    Returns Comparator

greaterEqualTo

  • greaterEqualTo(value: any, variable?: undefined | false | true): function
  • Greater or equal to comparator for use in where clauses.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ age: greaterEqualTo(18) })
    // WHERE age >= 18
    
    query.where({ age: greaterEqualTo('clientAge', true) })
    // WHERE age >= clientAge

    Parameters

    • value: any
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

greaterThan

  • greaterThan(value: any, variable?: undefined | false | true): function
  • Greater than comparator for use in where clauses.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ age: greaterThan(18) })
    // WHERE age > 18
    
    query.where({ age: greaterThan('clientAge', true) })
    // WHERE age > clientAge

    Parameters

    • value: any
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

hasLabel

inArray

  • inArray(value: any[], variable?: undefined | false | true): function
  • In comparator for use in where clauses.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ name: inArray([ 'steve', 'william' ]) })
    // WHERE name IN [ 'steve', 'william' ]
    
    query.where({ name: inArray('clientNames', true) })
    // WHERE name IN clientNames

    Parameters

    • value: any[]
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

isCredentials

  • isCredentials(credentials: any): credentials is Credentials
  • Parameters

    • credentials: any

    Returns credentials is Credentials

isNull

  • Is null comparator for use in where clauses. Note that this comparator does not accept any arguments

    query.where({ name: isNull() })
    // WHERE name IS NULL

    Returns Comparator

lessEqualTo

  • lessEqualTo(value: any, variable?: undefined | false | true): function
  • Less or equal to comparator for use in where clauses.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ age: lessEqualTo(18) })
    // WHERE age <= 18
    
    query.where({ age: lessEqualTo('clientAge', true) })
    // WHERE age >= clientAge

    Parameters

    • value: any
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

lessThan

  • lessThan(value: any, variable?: undefined | false | true): function
  • Less than comparator for use in where clauses.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ age: lessThan(18) })
    // WHERE age < 18
    
    query.where({ age: lessThan('clientAge', true) })
    // WHERE age < clientAge

    Parameters

    • value: any
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

node

  • node(name?: Many<string> | Dictionary<any>, labels?: Many<string> | Dictionary<any>, conditions?: Dictionary<any>): NodePattern
  • Creates a node pattern like (parent:Person { name: 'Gwenn' }).

    All of the arguments are optional and most of the time you can supply only the ones you want, assuming you keep the order the same of course.

    Use the following signatures as a reference:

    node(conditions: Dictionary<any>)
    node(labels: string[], conditions?: Dictionary<any>)
    node(name: string, conditions?: Dictionary<any>)
    node(name: string, labels?: string | string[], conditions?: Dictionary<any>)

    Note that labels must be an array when it is the first argument.

    Some examples

    node()
    // ()
    
    node('parent')
    // (parent)
    
    node('parent', 'Person')
    // (parent:Person)
    
    node([ 'Person' ])
    // (:Person)
    
    node('parent', [ 'Person', 'Adult' ])
    // (parent:Person:Adult)
    
    node({ name: 'Gwenn' })
    // ({ name: 'Gwenn' })
    
    node('parent', { name: 'Gwenn' })
    // (parent { name: 'Gwenn' })
    
    node([ 'Person' ], { name: 'Gwenn' })
    // (:Person { name: 'Gwenn' })
    
    node('parent', 'Person', { name: 'Gwenn' })
    // (parent:Person { name: 'Gwenn' })

    For more details on node patterns see the cypher docs

    Parameters

    • Optional name: Many<string> | Dictionary<any>
    • Optional labels: Many<string> | Dictionary<any>
    • Optional conditions: Dictionary<any>

      A dictionary of conditions to attach to the node. These are stored as parameters so there is no need to worry about escaping.

    Returns NodePattern

    An object representing the node pattern.

not

  • not(conditions: AnyConditions): WhereNot
  • NOT operator to use in where clauses.

    query.where(not([
      { 'person.name': 'Steve' },
      { 'person.age': greaterThan(18) },
    ]));
    // WHERE NOT (person.name = 'Steve' AND person.age > 18)

    Note that this method only accepts an array of conditions.

    Parameters

    • conditions: AnyConditions

    Returns WhereNot

or

  • or(conditions: OrConditions): WhereOr
  • OR operator to use in where clauses. This is the default operator when supplying an array to where so you will probably never need to use this unless you'd like to make it explicit.

    query.where(or([
      { 'person.name': 'Steve' },
      { 'person.age': greaterThan(18) },
    ]));
    // WHERE person.name = 'Steve' OR person.age > 18

    Note that this method only accepts an array of conditions.

    Parameters

    • conditions: OrConditions

    Returns WhereOr

regexp

  • regexp(exp: string | RegExp, insensitive?: undefined | false | true, variable?: undefined | false | true): function
  • Regexp comparator for use in where clauses. Also accepts a case insensitive to make it easier to add the '(?i)' flag to the start of your regexp. If you are already using flags in your regexp, you should not set insensitive to true because it will prepend '(?i)' which will make your regexp malformed.

    For convenience you can also pass a Javascript RegExp object into this comparator, which will then be converted into a string before it is passed to cypher. However, beware that the cypher regexp syntax is inherited from java, and may have slight differences to the Javascript syntax. For example, Javascript RegExp flags will not be preserved when sent to cypher.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ name: regexp('s.*e') })
    // WHERE name =~ 's.*e'
    
    query.where({ name: regexp('s.*e', true) })
    // WHERE name =~ '(?i)s.*e'
    
    query.where({ name: regexp('clientPattern', false, true) })
    // WHERE name =~ clientPattern

    Parameters

    • exp: string | RegExp
    • Optional insensitive: undefined | false | true
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

relation

  • relation(dir: RelationDirection, name?: Many<string> | Dictionary<any> | PathLength, labels?: Many<string> | Dictionary<any> | PathLength, conditions?: Dictionary<any> | PathLength, length?: PathLength): RelationPattern
  • Creates a relation pattern like -[rel:FriendsWith { active: true }]->.

    The only required argument is direction. All other arguments are optional and all combinations of them are valid. The only exception is that when labels is the first argument after direction, it must be an array, otherwise it will be interpreted as the relation name.

    Some examples

    relation('either')
    //  --
    
    relation('out', 'rel')
    //  -[rel]->
    
    relation('out', 'rel', 'FriendsWith')
    //  -[rel:FriendsWith]->
    
    relation('in', [ 'FriendsWith', 'RelatedTo' ])
    // <-[:FriendsWith|RelatedTo]-
    // Note that this will match a relation with either the FriendsWith label or
    // the RelatedTo label. You cannot use this syntax when creating relations.
    
    relation('in', [4, 10])
    // <-[*4..10]-
    
    relation('in', { active: true })
    // <-[{ active: true }]
    
    relation('in', 'rel', { active: true })
    // <-[rel { active: true }]-
    
    relation('either', [ 'FriendsWith' ], { active: true })
    //  -[:FriendsWith { active: true }]-
    
    relation('either', 'rel', 'FriendsWith', { active: true }, 3)
    //  -[rel:FriendsWith*3 { active: true }]-
    
    relation('either', 'rel', 'FriendsWith', { active: true }, [ 3 ])
    //  -[rel:FriendsWith*3.. { active: true }]-
    
    relation('either', 'rel', 'FriendsWith', { active: true }, [ 3, 5 ])
    //  -[rel:FriendsWith*3..5 { active: true }]-
    
    relation('either', 'rel', 'FriendsWith', { active: true }, '*')
    //  -[rel:FriendsWith* { active: true }]-

    For more details on relation patterns see the cypher docs.

    Parameters

    • dir: RelationDirection

      Direction of the relation. in means to the left, out means to the right and either means no direction.

    • Optional name: Many<string> | Dictionary<any> | PathLength
    • Optional labels: Many<string> | Dictionary<any> | PathLength
    • Optional conditions: Dictionary<any> | PathLength
    • Optional length: PathLength

      Length of the relation for flexible length paths. Can be the string '*' to represent any length, a single number 3 to represent the maximum length of the path, or an array of two numbers which represent the minimum and maximum length of the path. When passing an array, the second number is optional, see the examples above.

    Returns RelationPattern

    An object representing the relation pattern.

startsWith

  • startsWith(value: string, variable?: undefined | false | true): function
  • Starts with comparator for use in where clauses.

    If you want to compare against a Neo4j variable you can set variable to true and the value will be inserted literally into the query.

    query.where({ name: startsWith('steve') })
    // WHERE name STARTS WITH 'steve'
    
    query.where({ name: startsWith('clientName', true) })
    // WHERE name STARTS WITH clientName

    Parameters

    • value: string
    • Optional variable: undefined | false | true

    Returns function

      • (params: ParameterBag, name: string): string
      • Parameters

        • params: ParameterBag
        • name: string

        Returns string

xor

  • xor(conditions: OrConditions): WhereXor
  • XOR operator to use in where clauses.

    query.where(xor([
      { 'person.name': 'Steve' },
      { 'person.age': greaterThan(18) },
    ]));
    // WHERE person.name = 'Steve' XOR person.age > 18

    Note that this method only accepts an array of conditions.

    Parameters

    • conditions: OrConditions

    Returns WhereXor

Object literals

Const comparisions

comparisions: object

between

between: between

contains

contains: contains

endsWith

endsWith: endsWith

equals

equals: equals

exists

exists: exists

greaterEqualTo

greaterEqualTo: greaterEqualTo

greaterThan

greaterThan: greaterThan

hasLabel

hasLabel: hasLabel

inArray

inArray: inArray

isNull

isNull: isNull

lessEqualTo

lessEqualTo: lessEqualTo

lessThan

lessThan: lessThan

regexp

regexp: regexp

startsWith

startsWith: startsWith

Const operators

operators: object

and

and: and

not

not: not

or

or: or

xor

xor: xor

Legend

  • Module
  • Object literal
  • Variable
  • Function
  • Function with type parameter
  • Index signature
  • Type alias
  • Type alias with type parameter
  • Enumeration
  • Enumeration member
  • Property
  • Method
  • Interface
  • Interface with type parameter
  • Constructor
  • Property
  • Method
  • Index signature
  • Class
  • Class with type parameter
  • Constructor
  • Property
  • Method
  • Accessor
  • Index signature
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Inherited accessor
  • Protected property
  • Protected method
  • Protected accessor
  • Private property
  • Private method
  • Private accessor
  • Static property
  • Static method

Generated using TypeDoc