npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

guaphy

v1.1.4

Published

Guaphy is a javascript OGM for graph databases, Guaphy supports neo4j cypher language

Downloads

36

Readme

Guaphy

Guaphy is a javascript OGM for graph databases, Guaphy supports neo4j cypher language



How To Install

yarn add guaphy

Default Env

NEO4J_PROTOCOL = 'bolt'
NEO4J_HOST = 'localhost'
NEO4J_REPLICA_HOST = 'localhost'
NEO4J_PORT = '7687'
NEO4J_USER = 'neo4j'
NEO4J_PASSWORD = 'leeto'
NEO4J_ENTERPRISE='false'
NEO4J_DATABASE = 'neo4j'

Advanced Env

NEO4J_ENCRYPTION = 'encrypted'
NEO4J_TRUST = 'trust'
NEO4J_TRUSTED_CERTIFICATES = 'trustedCertificates'
NEO4J_KNOWN_HOSTS = 'knownHosts'
NEO4J_MAX_CONNECTION_POOLSIZE = 'maxConnectionPoolSize'
NEO4J_MAX_TRANSACTION_RETRY_TIME = 'maxTransactionRetryTime'
NEO4J_LOAD_BALANCING_STRATEGY = 'loadBalancingStrategy'
NEO4J_MAX_CONNECTION_LIFETIME = 'maxConnectionLifetime'
NEO4J_CONNECTION_TIMEOUT = 'connectionTimeout'
NEO4J_DISABLE_LOSSLESS_INTEGERS = 'disableLosslessIntegers'
NEO4J_LOGGING_LEVEL = 'logging'

Model

Example model

'use strict'

const { Model } = require("guaphy")
const Movie = require("./Movie")

class Person extends Model {
  _labels = ['Person']
  _softDeletes = true
  _timestamps = true

  actedInMovies() {
     return this.relatedToMany(Movie, "ACTED_IN")
  }

  directedMovies() {
     return this.relatedToMany(Movie, "DIRECTED")
  }
}

module.exports = Person

Ioc

Ioc helps you to avoid circular dependencies of models, so you can register your models before using them.

// index.js
const Person = require("Models/Person")
const Movie = require("Models/Movie")
const { Ioc } = require("guaphy")

Ioc.bind('Models/Person', Person)
Ioc.bind('Models/Movie', Movie)
// Modes/Person.js

'use strict'

const { Model } = require("guaphy")

class Person extends Model {
  _labels = ['Person']
  _softDeletes = true
  _timestamps = true

  actedInMovies() {
     return this.relatedToMany('Models/Movie', "ACTED_IN")
  }

  directedMovies() {
     return this.relatedToMany('Models/Movie', "DIRECTED")
  }
}

module.exports = Person

Static Methods

create

You can pass data directly to the model on creation, instead of manually setting attributes after instantiation:

const Person = require("Models/Person")

let person = await Person.create({ name: "Zorx" })

createMany

Like create, you can pass data directly for multiple instances on creation:

const Person = require("Models/Person")

let data = [{name: "Zorx"}, {name: "Leeto"}]
let people = await Person.createMany(data)

all

Select all nodes:

const Person = require("Models/Person")

const people = await Person.all()

first

Find the first node from the database:

const Person = require("Models/Person")

await Person.first()

last

Find the last node from the database:

const Person = require("Models/Person")

await Person.last()

find

Find a record using the primary key (always returns one record):

const Person = require("Models/Person")

await Person.find(1)

findOrFail

FindOrFail a record using the primary key (always returns one record or an exception):

const Person = require("Models/Person")

await Person.findOrFail(1)

count

Return a count of records in a given result set

const Person = require("Models/Person")

let count = await Person.count()

destroy

The destroy method deletes an existing model by its primary key

const Person = require("Models/Person")

// Single destroy
let person = await Person.first();
await Person.destroy(person._id)
// Multiple destroy
let firstPerson = await Person.first();
let lastPerson = await Person.last();

await Person.destroy([firstPerson._id, lastPerson._id])

truncate

Delete all nodes.

const Person = require("Models/Person")

const people = await Person.truncate()

forceTruncate

const Person = require("Models/Person")

const people = await Person.forceTruncate()

as

change the variable with "as" method

let person = await Person.create({ name: "Zorx" })
let people = await Person.as('p').query().where('p.name', 'Zorx').return('p').fetch();

query

To obtain a Query Builder instance, call the model query method:

const Person = require("Models/Person")

const adults = await Person
.query()
.where('name', 'Zorx')
.return().fetch();

The fetch method is required to execute the query ensuring results return

Instance Methods

update

Update an instance:

const Person = require("Models/Person")

let person = await Person.find(1)
await person.update({ name: 'Leeto' })

instantiate and save

save

With models, instead of inserting raw values into the database, you persist the model instance which in turn makes the insert query for you. For example:

let person = new Person;
person.name = "Zorx"

await person.save()

fill

The fill method will override all existing key/pair values of the model instance :

let person = new Person;

person.fill({
  name: "Zorx"
})

await person.save()

change and save

let person = await Person.create({ name: "Zorx" })

person.name = "Leeto"

person = await person.save()

delete (soft delete)

A single model instance can be deleted by calling the delete method:

const Person = require("Models/Person")

let person = await Person.find(1)
await person.delete()

Delete method is a soft delete that means the deleted model instance, can be restored by using restore method

restore

Restore the deleted model instance

let deletedUerId = 1
let person = await Person.query().withTrashed().whereId(deletedUerId).return().first()

await person.restore()

forceDelete

Unlike delete method the forceDelete method will delete the model instance immediately

const Person = require("Models/Person")

let person = await Person.find(1)
await person.forceDelete()

Bulk Deletes

Bulk deletes are performed with the help of Query Builder:

const Person = require("Models/Person")

const adults = await Person
.query()
.where('name', 'Zorx')
.delete();

Relationships


RelatedToOne

attach

let user = await User.create({ name: "user" })

let role = await Role.create({ name: "admin" })

let relation = await user.role().attach(role)

attach with properties

let user = await User.create({ name: "user" })

let role = await Role.create({ name: "admin" })

let relation = await user.role().attach(role, {'since': 1999})

relation exists

let user = await User.create({ name: "user" })

let role = await Role.create({ name: "admin" })

await user.role().attach(role, {'since': 1999})

await user.role().exists(role) // true

update relation properties

let user = await User.create({ name: "user" })
let role = await Role.create({ name: "admin" })

let relation = await user.role().attach(role, {'since': 1999})
relation = await user.role().update(role, {'since': 2000})

get relation properties

let user = await User.create({ name: "user" })
let role = await Role.create({ name: "admin" })

let relation = await user.role().attach(role, {'since': 1999})

// Without eager loading
user = await User.first()
role = await user.role().load()

let properties = role.getRelationProperties()

// Lazy eager loading
user = await User.first()
role = await user.load('role')
properties = role.getRelationProperties()

// Eager loading
user = await User.query()
  .withRelation('role')
  .return()
  .first()

role = user.getRelated('role');
properties = role.getRelationProperties()

// Multiple toJson
let users = await User.query()
  .withRelation('role')
  .return()
  .fetch()

users = users.toJson()
properties = users[0].role.__relationProperties

// One toJson
user = await User.query()
  .withRelation('role')
  .return()
  .first()

user = user.toJson()
properties = user.role.__relationProperties

load without eager loading

let user = await User.create({ name: "user" })
let role = await Role.create({ name: "admin" })

await user.role().attach(role, {'since': 1999})

role = await user.role().load()

lazy eager loading

let user = await User.create({ name: "user" })
let role = await Role.create({ name: "admin" })

await user.role().attach(role, {'since': 1999})

let relatedRole = await user.load('role')
relatedRole = user.getRelated('role')

eager loading | withRelation

let user = await User.create({ name: "user" })
let role = await Role.create({ name: "admin" })

await user.role().attach(role, {'since': 1999})

let users = await User
  .query()
  .withRelation('role')
  .return()
  .fetch()

eager loading | withRelation filter related

let user1 = await User.create({ name: "user1" })
let user2 = await User.create({ name: "user2" })
let role1 = await Role.create({ name: "admin" })
let role2 = await Role.create({ name: "manager" })

await user1.role().attach(role1, {'since': 1999})
await user2.role().attach(role2, {'since': 2000})

let users = await User
  .query()
  .withRelation('role', c => c.where('name', 'admin'))
  .return()
  .fetch()

eager loading | withRelation filter parent

let user1 = await User.create({ name: "user1" })
let user2 = await User.create({ name: "user2" })
let role1 = await Role.create({ name: "admin" })
let role2 = await Role.create({ name: "manager" })

await user1.role().attach(role1, {'since': 1999})
await user2.role().attach(role2, {'since': 2000})

let users = await User
  .query()
  .where('name', 'user2')
  .withRelation('role')
  .return()
  .fetch()

eager loading | multiple withRelation

let user = await User.create({ name: "user" })
let role1 = await Role.create({ name: "admin" })
let role2 = await Role.create({ name: "root" })

await user.role().attach(role1)
await user.notRole().attach(role2)

let users = await User
  .query()
  .withRelation('role')
  .withRelation('notRole')
  .return()
  .fetch()

detach

let user = await User.create({ name: "user" })
let role = await Role.create({ name: "admin" })

await user.role().attach(role)
await user.role().detach(role)

RelatedToMany

attach

let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })

let relation = await person.actedInMovies().attach(movie)

attach Many

let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })
let movie2  = await Movie.create({ name: "The Equalizer2" })

let relation = await person.actedInMovies().attachMany([movie1, movie2])

relation exists

let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })

let relation = await person.actedInMovies().attach(movie)

await person.actedInMovies().exists(movie) // true

attach with properties

let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })

let relation = await person.actedInMovies().attach(movie, {name: 'Robert McCall'})

attach many with properties

let person = await Person.create({ name: "Denzel Washington" })
let movie1  = await Movie.create({ name: "The Equalizer" })
let movie2  = await Movie.create({ name: "The Equalizer2" })

let relation = await person.actedInMovies().attach(
  [movie1, movie2],
  [{name: 'Robert McCall'}, {name: 'Robert McCall'}]
)

update relation properties

let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })

relation = await person.actedInMovies().update(movie, {name: 'Robert'})

get relation properties

let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })

// Without eager loading
person = await Person.first()
let movies = await person.actedInMovies().load()

// Lazy eager loading
person = await Person.first()
movies = await person.load('actedInMovies')
properties = movies.first().getRelationProperties()

// Eager loading
person = await Person.query()
  .withRelation('actedInMovies')
  .return()
  .first()

movies = person.getRelated('actedInMovies');
properties = movies.first().getRelationProperties()

// Multiple toJson
let people = await Person.query()
  .withRelation('actedInMovies')
  .return()
  .fetch()

people = people.toJson()
properties = people[0].actedInMovies[0].__relationProperties

// One toJson
person = await Person.query()
  .withRelation('actedInMovies')
  .return()
  .first()

person = person.toJson()
properties = person.actedInMovies[0].__relationProperties

load without eager loading

let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })

await person.actedInMovies().attach(movie)

let movies = await person.actedInMovies().load()

lazy eager loading

let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })

await person.actedInMovies().attach(movie)

let relatedMovies = await person.load('actedInMovies')

reverse relation

actors() {
 return this.relatedToMany('Models/Person', "ACTED_IN", true)
}
let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })

await person.actedInMovies().attach(movie)

movie = await Movie.first()
let relatedActors = await movie.load('actors')

eager loading | withCountRelation

let person  = await Person.create({ name: "Denzel Washington" })
let movie1  = await Movie.create({ name: "The Equalizer" })
let movie2  = await Movie.create({ name: "The Equalizer2" })

await person.actedInMovies().attach(movie1)
await person.actedInMovies().attach(movie2)

let p = await Person
  .query()
  .withCountRelation('actedInMovies')
  .return()
  .first()

// p.toJson().actedInMoviesCount == 2

eager loading | withRelation

let person  = await Person.create({ name: "Denzel Washington" })
let movie1  = await Movie.create({ name: "The Equalizer" })
let movie2  = await Movie.create({ name: "The Equalizer2" })

await person.actedInMovies().attach(movie1)
await person.actedInMovies().attach(movie2)

let people = await Person
  .query()
  .withRelation('actedInMovies')
  .return()
  .fetch()

movie = await Movie.first()
let relatedActors = await movie.load('actors')

eager loading | withRelation filter related

let person  = await Person.create({ name: "Denzel Washington" })
let person2 = await Person.create({ name: "Keanu Reeves" })
let movie1  = await Movie.create({ name: "The Equalizer" })
let movie2  = await Movie.create({ name: "The Equalizer2" })
let movie3  = await Movie.create({ name: "John Wick" })

await person.actedInMovies().attach(movie1)
await person.actedInMovies().attach(movie2)
await person2.actedInMovies().attach(movie3)

let people = await Person
  .query()
  .withRelation('actedInMovies', c => c.where('name', 'The Equalizer'))
  .return()
  .fetch()

eager loading | withRelation limit

let person  = await Person.create({ name: "Denzel Washington" })
let person2 = await Person.create({ name: "Keanu Reeves" })
let movie1  = await Movie.create({ name: "The Equalizer" })
let movie2  = await Movie.create({ name: "The Equalizer2" })
let movie3  = await Movie.create({ name: "John Wick" })

await person.actedInMovies().attach(movie1)
await person.actedInMovies().attach(movie2)
await person2.actedInMovies().attach(movie3)

let people = await Person
  .query()
  .withRelation('actedInMovies', 5)
  .return()
  .fetch()

eager loading | withRelation filter related and limit

let person  = await Person.create({ name: "Denzel Washington" })
let person2 = await Person.create({ name: "Keanu Reeves" })
let movie1  = await Movie.create({ name: "The Equalizer" })
let movie2  = await Movie.create({ name: "The Equalizer2" })
let movie3  = await Movie.create({ name: "John Wick" })

await person.actedInMovies().attach(movie1)
await person.actedInMovies().attach(movie2)
await person2.actedInMovies().attach(movie3)

let people = await Person
  .query()
  .withRelation('actedInMovies', c => c.where('name', 'The Equalizer'), 5)
  .return()
  .fetch()

eager loading | withRelation filter parent

let person1 = await Person.create({ name: "Denzel Washington" })
let person2 = await Person.create({ name: "Keanu Reeves" })
let movie1  = await Movie.create({ name: "The Equalizer" })
let movie2  = await Movie.create({ name: "The Equalizer2" })

await person1.actedInMovies().attach(movieP1)
await person2.actedInMovies().attach(movieP2)

let people = await Person
  .query()
  .where('name', 'Keanu Reeves')
  .withRelation('actedInMovies')
  .return()
  .fetch()

eager loading | multiple withRelation

let person = await Person.create({ name: "Denzel Washington" })
let movie = await Movie.create({ name: "The Equalizer" })
let directedMovie = await Movie.create({ name: "Fences" })

await person.actedInMovies().attach(movie)
await person.directedMovies().attach(directedMovie)

let people = await Person
  .query()
  .withRelation('actedInMovies')
  .withRelation('directedMovies')
  .return()
  .fetch()

detach

let person = await Person.create({ name: "Denzel Washington" })
let movie  = await Movie.create({ name: "The Equalizer" })

await person.actedInMovies().attach(movie)
await person.actedInMovies().detach(movie)

Cypher Query Builder

Require Query Builder

const { QueryBuilder } = require("guaphy")
const queryBuilder = new QueryBuilder

cypher

cypher method

let result = await queryBuilder
.cypher('CREATE (a:Person {name: "leeto"}), (b:User {name: "zorx"}) RETURN a,b')
.fetch()

chain cypher methods

let result = await queryBuilder
.cypher('CREATE (a:Person {name: "leeto"}), (b:Person {name: "zorx"})')
.cypher('RETURN a,b')

toCypher | toCYPHER

Returns cypher query to string

let query = 'CREATE (a:Person {name: "zorx"}) RETURN a';

let result1 = queryBuilder.cypher(query).toCypher()
let result2 = queryBuilder.cypher(query).toCYPHER()

// result1
// CREATE (a:Person {name: "zorx"}) RETURN a

// result2
// CREATE (a:Person {name: "zorx"}) RETURN a

fetch

The fetch method is required to execute the query ensuring results return.

let result = await queryBuilder
.cypher('MATCH (n:Person) RETURN n')
.fetch()

first

Return the first match record

let result = await queryBuilder
.cypher('MATCH (n:Person) RETURN n')
.first()

count

Return a count of records.

let count = await queryBuilder.cypher('MATCH (n:Person) RETURN n').count()

Clauses

limit

Limit the number of the results

let result = await queryBuilder
.cypher('MATCH (n:Person) RETURN n')
.limit(1)
.fetch()

orderBy

The orderBy method can takes string, array and array of object

queryBuilder.orderBy('a.name') // equals to 'ORDER BY a.name')
queryBuilder.orderBy('a.name', 'DESC') // equals to 'ORDER BY a.name DESC')
queryBuilder.orderBy(['a.name', 'b.name']) // equals to 'ORDER BY a.name,b.name')
queryBuilder.orderBy(['a.name', 'b.name'], 'DESC') // equals to 'ORDER BY a.name DESC,b.name DESC')
queryBuilder.orderBy([{'a.name': 'DESC'}, 'b.name']) // equals to 'ORDER BY a.name DESC,b.name')
queryBuilder.orderBy([{'a.name': 'DESC'}, {'b.name': 'DESC'}]) // equals to 'ORDER BY a.name DESC,b.name DESC')
queryBuilder.orderBy([{'a.name': 'DESC', 'b.name': 'DESC'}]) // equals to 'ORDER BY a.name DESC,b.name DESC')
queryBuilder.orderBy(['a.name', {'b.name': 'DESC'}]) // equals to 'ORDER BY a.name,b.name DESC')

return

The return method takes as many arguments as you need.

queryBuilder.return('a', 'b') // equals to RETURN a,b
queryBuilder.return('a', 'b', 'c') // equals to RETURN a,b,c

node

The node method takes three arguments, the first is the field, the second is the label, and the third is the params.

queryBuilder.node('') // equals to ()
queryBuilder.node('n') // equals to (n)
queryBuilder.node(null, 'Movie') // equals to (:Movie)
queryBuilder.node('movie', 'Movie') // equals to (movie:Movie)
queryBuilder.node('director', 'Movie', {name: 'Oliver Stone'}) // equals to (director:Movie { name: 'Oliver Stone' })
queryBuilder.node('director', {name: 'Oliver Stone'}) // equals to (director { name: 'Oliver Stone' })

relation

The relation method takes three arguments, the first is the field, the second is the label, and the third is the params.

queryBuilder.relation() // equals to  '--'
queryBuilder.relation('r') // equals to  '-[r]-'
queryBuilder.relation(null, 'ACTED_IN') // equals to  '-[:ACTED_IN]-'
queryBuilder.relation(':ACTED_IN') // equals to  '-[:ACTED_IN]-'
queryBuilder.relation('r', 'ACTED_IN') // equals to  '-[r:ACTED_IN]-'
queryBuilder.relation(
      r => { return r.relate(':ACTED_IN').relate(':DIRECTED')}
    )
// equals to  '-[:ACTED_IN|:DIRECTED]-'
queryBuilder.relation(
      r => {return r.relate('r', 'ACTED_IN').relate(':DIRECTED')}
    )
// equals to  '-[r:ACTED_IN|:DIRECTED]-'
queryBuilder.relation(
      r => {return r.relate('r', 'ACTED_IN').relate('d', 'DIRECTED')}
    )
// equals to  '-[r:ACTED_IN|d:DIRECTED]-'
queryBuilder.relation(
      r => {return r.relate(null, 'ACTED_IN').relate('d', 'DIRECTED')}
    )
// equals to  '-[:ACTED_IN|d:DIRECTED]-'
queryBuilder.relation(
      r => {return r.relate(null, 'ACTED_IN').relate('d', 'DIRECTED').relate('m', 'MANAGED')}
    )
// equals to  '-[:ACTED_IN|d:DIRECTED|m:MANAGED]-'

relationIn

The relationIn method takes three arguments, the first is the field, the second is the label, and the third is the params, for example:

queryBuilder.relationIn() // equals to '<--'
queryBuilder.relationIn('r') // equals to '<-[r]-'
queryBuilder.relationIn(null, 'ACTED_IN') // equals to '<-[:ACTED_IN]-'
queryBuilder.relationIn(':ACTED_IN') // equals to '<-[:ACTED_IN]-'
queryBuilder.relationIn('r', 'ACTED_IN') // equals to '<-[r:ACTED_IN]-'
queryBuilder.relationIn(
    r => {return r.relate(':ACTED_IN').relate(':DIRECTED')})

// equals to '<-[:ACTED_IN|:DIRECTED]-'
queryBuilder.relationIn(
    r => {return r.relate('r', 'ACTED_IN').relate(':DIRECTED')})

// equals to '<-[r:ACTED_IN|:DIRECTED]-'
queryBuilder.relationIn(
    r => {return r.relate('r', 'ACTED_IN').relate('d', 'DIRECTED')})

// equals to '<-[r:ACTED_IN|d:DIRECTED]-'
queryBuilder.relationIn(
    r => {return r.relate(null, 'ACTED_IN').relate('d', 'DIRECTED')})

// equals to '<-[:ACTED_IN|d:DIRECTED]-'
queryBuilder.relationIn(
    r => {return r.relate(null, 'ACTED_IN').relate('d', 'DIRECTED').relate('m', 'MANAGED')})

// equals to '<-[:ACTED_IN|d:DIRECTED|m:MANAGED]-'

relationOut

Like the relationIn, but it's in the opposite direction, for example:

queryBuilder.relationOut() // equals to '-->'
queryBuilder.relationOut('r') // equals to '-[r]->'
queryBuilder.relationOut(null, 'ACTED_IN') // equals to '-[:ACTED_IN]->'
queryBuilder.relationOut(':ACTED_IN') // equals to '-[:ACTED_IN]->'
queryBuilder.relationOut('r', 'ACTED_IN') // equals to '-[r:ACTED_IN]->'
queryBuilder.relationOut('r', 'ACTED_IN', {role: 'Sophia'}) // equals to "-[r:ACTED_IN { role: 'Sophia' }]->"
queryBuilder.relationOut(
    r => {return r.relate(':ACTED_IN').relate(null, 'DIRECTED', {since: 1985})})

// equals to '-[:ACTED_IN|:DIRECTED { since: 1985 }]->'
queryBuilder.relationOut(
    r => {return r.relate('r', 'ACTED_IN').relate(':DIRECTED')})

// equals to '-[r:ACTED_IN|:DIRECTED]->'
queryBuilder.relationOut(
    r => {return r.relate('r', 'ACTED_IN').relate('d', 'DIRECTED')})

// equals to '-[r:ACTED_IN|d:DIRECTED]->'
queryBuilder.relationOut(
    r => {return r.relate(null, 'ACTED_IN').relate('d', 'DIRECTED')})

//  equals to '-[:ACTED_IN|d:DIRECTED]->'
queryBuilder.relationOut(
    r => {return r.relate(null, 'ACTED_IN').relate('d', 'DIRECTED').relate('m', 'MANAGED')})

// equals to '-[:ACTED_IN|d:DIRECTED|m:MANAGED]->'

match

queryBuilder.match()

// equals to 'MATCH')
queryBuilder.match(c => { return c.node('n') })

// equals to 'MATCH (n)'
queryBuilder.match(c => {
    return c.node('movie', 'Movie')})

// equals to 'MATCH (movie:Movie)'
queryBuilder.match(c => {
    return c.node('director', 'Movie', {name: 'Oliver Stone'})})

// equals to "MATCH (director:Movie { name: 'Oliver Stone' })"
queryBuilder.match(c => {
    return c.node('director', {name: 'Oliver Stone'})})

// equals to "MATCH (director { name: 'Oliver Stone' })"
queryBuilder.match([
    c => c.node('charlie', 'Person', {name: 'Charlie Sheen'}),
    c => c.node('rob', 'Person', {name: 'Rob Reiner'})
])

// equals to "MATCH (charlie:Person { name: 'Charlie Sheen' }), (rob:Person { name: 'Rob Reiner' })"

optional match

queryBuilder.optionalMatch(c => {
    return c.node('n')
})

// equals to 'OPTIONAL MATCH (n)'
queryBuilder.optionalMatch(c => {
    return c.node('movie', 'Movie')
})

// equals to 'OPTIONAL MATCH (movie:Movie)'
queryBuilder.optionalMatch(c => {
    return c.node('director', 'Movie', {name: 'Oliver Stone'})
})

// equals to "OPTIONAL MATCH (director:Movie { name: 'Oliver Stone' })"
queryBuilder.optionalMatch(c => {
    return c.node('director', {name: 'Oliver Stone'})
})

// equals to "OPTIONAL MATCH (director { name: 'Oliver Stone' })"
queryBuilder.optionalMatch([
    c => c.node('charlie', 'Person', {name: 'Charlie Sheen'}),
    c => c.node('rob', 'Person', {name: 'Rob Reiner'})
])

// equals to "OPTIONAL MATCH (charlie:Person { name: 'Charlie Sheen' }), (rob:Person { name: 'Rob Reiner' })"

group

queryBuilder.match(c => c.node('p', 'Person'))
.group(g => {
    return g.optionalMatch(o => {
        return o.node('p')
            .relationOut(':ACTED_IN')
            .node('m1', 'Movie')
    })
    .with('p', 'collect(m1) AS actedInMovies')
})
.group(g => {
    return g.optionalMatch(o => {
        return o.node('p')
            .relationOut(':DIRECTED')
            .node('m2', 'Movie')
    })
    .with('p', 'actedInMovies', 'collect(m1) AS directedMovies')
})
.return('p', 'actedInMovies', 'directedMovies')

// That equals to "MATCH (p:Person) OPTIONAL MATCH (p) -[:ACTED_IN]-> (m1:Movie) WITH p,collect(m1) AS actedInMovies OPTIONAL MATCH (p) -[:DIRECTED]-> (m2:Movie) WITH p,actedInMovies,collect(m1) AS directedMovies RETURN p,actedInMovies,directedMovies"

complex match relation

queryBuilder.match(m => {
    return m.node('director', {name: 'Oliver Stone'})
        .relation()
        .node('movie')
})

// equals to "MATCH (director { name: 'Oliver Stone' }) -- (movie)"
queryBuilder.match(m => {
    return m.node(':Person', {name: 'Oliver Stone'})
        .relation()
        .node('movie', 'Movie')
})

// equals to "MATCH (:Person { name: 'Oliver Stone' }) -- (movie:Movie)"
queryBuilder.match(m => {
    return m.node(':Person', {name: 'Oliver Stone'})
        .relationOut('r')
        .node('movie')
})

// equals to "MATCH (:Person { name: 'Oliver Stone' }) -[r]-> (movie)"
queryBuilder.match(m => {
    return m.node('wallstreet', {title: 'Wall Street'})
        .relationIn(r => {
            return r.relate(':ACTED_IN')
                .relate(':DIRECTED')
        })
        .node('person')
})

// equals to "MATCH (wallstreet { title: 'Wall Street' }) <-[:ACTED_IN|:DIRECTED]- (person)"
queryBuilder.match(m => {
    return m.node('charlie', {name: 'Charlie Sheen'})
        .relationOut(':ACTED_IN')
        .node('movie')
        .relationIn(':DIRECTED')
        .node('director')
}).return('movie.title', 'director.name')

// equals to "MATCH (charlie { name: 'Charlie Sheen' }) -[:ACTED_IN]-> (movie) <-[:DIRECTED]- (director) RETURN movie.title,director.name"

with

queryBuilder.with('n') // equals to  'WITH n'
queryBuilder.with('otherPerson', 'count(*) AS foaf') // equals to  'WITH otherPerson,count(*) AS foaf'

skip

queryBuilder.skip(1) // equals to 'SKIP 1'
queryBuilder.skip('toInteger(3*rand()) + 1') // equals to 'SKIP toInteger(3*rand()) + 1'

delete

queryBuilder.delete('n', false) // equals to 'DELETE n'
queryBuilder.delete('n') // equals to 'DETACH DELETE n'

restore

queryBuilder.restore('n') // equals to 'SET n.deleted_at = null'

remove

queryBuilder.remove('n.age') // equals to 'REMOVE n.age'
queryBuilder.remove('n:Algerian') // equals to 'REMOVE n:Algerian'

as

queryBuilder.return('n.age').as('y') // equals to 'RETURN n.age AS y'

onMatch

queryBuilder.onMatch() // equals to 'ON MATCH'

onCreate

queryBuilder.onCreate() // equals to 'ON CREATE'

call

queryBuilder.call('db.labels') // equals to 'CALL db.labels'
queryBuilder.call(c => c.with('x').return('x * 10').as('y')) // equals to 'CALL { WITH x RETURN x * 10 AS y }'

union

queryBuilder.union() // equals to 'UNION'
queryBuilder.union('ALL') // equals to 'UNION ALL'

merge

queryBuilder.merge() // equals to 'MERGE'
queryBuilder.merge(m => m.node('n')) // equals to 'MERGE (n)'
queryBuilder.merge(m => m.node('movie', 'Movie')) // equals to 'MERGE (movie:Movie)'
queryBuilder.merge(m => m.node('director', 'Movie', {name: 'Oliver Stone'})) // equals to "MERGE (director:Movie { name: 'Oliver Stone' })"
queryBuilder.merge(m => m.node('charlie', {name: 'Charlie Sheen', age: 10})) // equals to "MERGE (charlie { name: 'Charlie Sheen', age: 10 })"
queryBuilder.merge(m => m.node('amine', 'Person', {name: 'Amine OUDJEHIH'})) // equals to "MERGE (amine:Person { name: 'Amine OUDJEHIH' })"
queryBuilder.merge(m => {
return m.node('zorx')
.relationOut('r', 'ACTED_IN')
.node('wallStreet')
})
// equals to  "MERGE (zorx) -[r:ACTED_IN]-> (wallStreet)"
queryBuilder.merge(m => {
return m.node('person', 'Person')
.onMatch()
.set('person.found', true)
})
// equals to 'MERGE (person:Person) ON MATCH SET person.found = true'

create

queryBuilder.create() // equals to 'CREATE'
queryBuilder.create(m => m.node('n')) // equals to 'CREATE (n)'
queryBuilder.create([ m => m.node('n'), m => m.node('b') ])
// equals to 'CREATE (n), (b)'
queryBuilder.create(m => m.node('movie', 'Movie'))
// equals to 'CREATE (movie:Movie)'
queryBuilder.create(m => m.node('charlie', {name: 'Charlie Sheen', age: 10}))
// equals to "CREATE (charlie { name: 'Charlie Sheen', age: 10 })"
queryBuilder.create(m => m.node('amine', 'Person', {name: 'Amine OUDJEHIH'}))
// equals to "CREATE (amine:Person { name: 'Amine OUDJEHIH' })"
queryBuilder
.create(m => {
  return m.node('zorx')
  .relationOut('r', 'ACTED_IN')
  .node('wallStreet')
})
// equals to "CREATE (zorx) -[r:ACTED_IN]-> (wallStreet)"

set | update

queryBuilder.set({
  'p.name': 'Amine',
  'p.position': 'Maintainer'
})
// equals to "SET p.name = 'Amine',p.position = 'Maintainer'"
queryBuilder.set('p.name', 'Amine')
// equals to "SET p.name = 'Amine'")
queryBuilder.set('p', {
  name: 'Amine',
  position: 'Maintainer'
})
// equals to "SET p = { name: 'Amine', position: 'Maintainer' }"
queryBuilder.update({
  'p.name': 'Amine',
  'p.position': 'Maintainer'
})
// equals to "SET p.name = 'Amine',p.position = 'Maintainer'"
queryBuilder.update('p.name', 'Amine')
// equals to "SET p.name = 'Amine'")
queryBuilder.update('p', {
  name: 'Amine',
  position: 'Maintainer'
})
// equals to "SET p = { name: 'Amine', position: 'Maintainer' }"

unwind

queryBuilder.unwind([1, 2, 3], 'x') // equals to 'UNWIND [1,2,3] AS x'
queryBuilder.unwind('coll', 'x') // equals to 'UNWIND coll AS x'
queryBuilder.unwind('(a + b)', 'x') // equals to 'UNWIND (a + b) AS x'
queryBuilder.unwind([], 'empty') // equals to 'UNWIND [] AS empty'
queryBuilder.unwind(null, 'empty') // equals to 'UNWIND null AS empty'
queryBuilder.unwind("$events", 'event') // equals to 'UNWIND $events AS event'

Conditions

where external variable

queryBuilder.where('a.name', 'zorx') // equals to "WHERE a.name = 'zorx'"

where local variable

queryBuilder.where('a.name', '$b.name') // equals to "WHERE a.name = b.name"

where symbol

queryBuilder.where('a.age', '>=', 18) // equals to "WHERE a.age >= 18"

where id

queryBuilder.whereId('n', 17) // equals to "WHERE id(n) = 17")
queryBuilder.whereId(17) // equals to "WHERE id() = 17")

where between

queryBuilder.whereBetween('a.age', 17, 18, '<', '<') // equals to "WHERE 17 < a.age < 18"

where exists

queryBuilder.whereExists('a.age') // equals to "WHERE exists(a.age)"

where contains

queryBuilder.whereContains('a.name', 'z') // equals to "WHERE a.name CONTAINS 'z'"

where startsWith

queryBuilder.whereStartsWith('a.name', 'z') // equals to "WHERE a.name STARTS WITH 'z'"

where endsWith

queryBuilder.whereEndsWith('a.name', 'z') // equals to "WHERE a.name ENDS WITH 'z'"

where regex

queryBuilder.whereRegex('a.name', 'z.*') // equals to "WHERE a.name =~ 'z.*'"

where in

queryBuilder.whereIn('a.age', [17, 18, 19]) // equals to "WHERE a.age IN [17,18,19]"

where id in

queryBuilder.whereIdIn([17, 18, 19]) // equals to "WHERE id() IN [17,18,19]"
queryBuilder.whereIdIn('n', [17, 18, 19]) // equals to "WHERE id(n) IN [17,18,19]"

where label

queryBuilder.whereLabel('a', 'Person') // equals to "WHERE a:Person"

where raw

queryBuilder.whereRaw('NOT (person)-->(peter)') // equals to "WHERE NOT (person)-->(peter)"

and

queryBuilder.where('a.age', 20).and('a.name', 'zorx') // equals to "WHERE a.age = 20 AND a.name = 'zorx'"

or

queryBuilder.where('a.age', 20).or('a.name', 'zorx') // equals to "WHERE a.age = 20 OR a.name = 'zorx'"

xor

queryBuilder.where('a.age', 20).xor('a.name', 'zorx') // equals to "WHERE a.age = 20 XOR a.name = 'zorx'"

orNot

queryBuilder.where('a.age', 20).orNot('a.name', 'Ted') // equals to "WHERE a.age = 20 OR NOT a.name = 'Ted'"

xorNot

queryBuilder.where('a.age', 20).xorNot('a.name', 'Ted') // equals to "WHERE a.age = 20 XOR NOT a.name = 'Ted'"

whereNot

queryBuilder.whereNot('a.age', 20) // equals to "WHERE NOT a.age = 20"

Combined Conditions

whereNot combine with other condition

queryBuilder.whereNot(e => {
    return e.whereExists('a.age')
  })
// equals to "WHERE NOT (exists(a.age))"
queryBuilder.whereNot(e => {
    return e.whereEndsWith('n.name', 'y')
  })
// equals to "WHERE NOT (n.name ENDS WITH 'y')"

complex query

queryBuilder.where('a.name', 'Peter')
    .xor(c => {
        return c.where('n.age', '<', 30)
        .and('n.name', 'Timothy')
    })
    .orNot(c => {
        return c.where('n.name', 'Timothy')
        .or('n.name', 'Peter')
    })

// equals to "WHERE a.name = 'Peter' XOR (n.age < 30 AND n.name = 'Timothy') OR NOT (n.name = 'Timothy' OR n.name = 'Peter')"

more complex query

queryBuilder
    .where('a.name', 'Peter')
    .xor(c => {
        return c.where(c => {
            return c.whereBetween('n.age', 30, 40)
                .or('n.age', '>', 40)
        })
        .and('n.name', 'Timothy')
    })
    .orNot(c => {
        return c.where('n.name', 'Timothy')
        .or(c => {
            return c.where('n.name', 'Peter')
                .and('n.name', 'Jim')
        })
    })

// equals to "WHERE a.name = 'Peter' XOR ((30 <= n.age <= 40 OR n.age > 40) AND n.name = 'Timothy') OR NOT (n.name = 'Timothy' OR (n.name = 'Peter' AND n.name = 'Jim'))"