All Projects → Yomguithereal → decypher

Yomguithereal / decypher

Licence: MIT license
A handful of cypher utilities for Node.js

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to decypher

Neo4j
Graphs for Everyone
Stars: ✭ 9,582 (+28082.35%)
Mutual labels:  neo4j, cypher
ml-models
Machine Learning Procedures and Functions for Neo4j
Stars: ✭ 63 (+85.29%)
Mutual labels:  neo4j, cypher
Cypher Dsl
A Java DSL for the Cypher Query Language
Stars: ✭ 116 (+241.18%)
Mutual labels:  neo4j, cypher
Cypher Stream
Neo4j Cypher queries as Node.js object streams
Stars: ✭ 58 (+70.59%)
Mutual labels:  neo4j, cypher
Movies Python Bolt
Neo4j Movies Example application with Flask backend using the neo4j-python-driver
Stars: ✭ 197 (+479.41%)
Mutual labels:  neo4j, cypher
Movies Java Bolt
Neo4j Movies Example application with SparkJava backend using the neo4j-java-driver
Stars: ✭ 66 (+94.12%)
Mutual labels:  neo4j, cypher
Public-Transport-SP-Graph-Database
Metropolitan Transport Network from São Paulo mapped in a NoSQL graph database.
Stars: ✭ 25 (-26.47%)
Mutual labels:  neo4j, cypher
R2d2 Cypher
Cypher support for the r2d2 connection pool
Stars: ✭ 8 (-76.47%)
Mutual labels:  neo4j, cypher
Jetbrains Plugin Graph Database Support
Graph Databases support for JetBrains family IDEs.
Stars: ✭ 169 (+397.06%)
Mutual labels:  neo4j, cypher
Neo4j Etl
Data import from relational databases to Neo4j.
Stars: ✭ 165 (+385.29%)
Mutual labels:  neo4j, cypher
Neo4j Tableau
Neo4j Tableau Integration via WDC
Stars: ✭ 56 (+64.71%)
Mutual labels:  neo4j, cypher
angular-neo4j
Neo4j Bolt driver wrapper for Angular
Stars: ✭ 18 (-47.06%)
Mutual labels:  neo4j, cypher
Neo4j Helm
Helm Charts for running Neo4j on Kubernetes
Stars: ✭ 43 (+26.47%)
Mutual labels:  neo4j, cypher
Stock Knowledge Graph
利用网络上公开的数据构建一个小型的证券知识图谱/知识库
Stars: ✭ 1,182 (+3376.47%)
Mutual labels:  neo4j, cypher
Scala Cypher Dsl
A type-safe Cypher Query Language DSL for Scala.
Stars: ✭ 34 (+0%)
Mutual labels:  neo4j, cypher
Movies Javascript Bolt
Neo4j Movies Example with webpack-in-browser app using the neo4j-javascript-driver
Stars: ✭ 123 (+261.76%)
Mutual labels:  neo4j, cypher
Neovis.js
Neo4j + vis.js = neovis.js. Graph visualizations in the browser with data from Neo4j.
Stars: ✭ 748 (+2100%)
Mutual labels:  neo4j, cypher
Node Neo4j
[RETIRED] Neo4j graph database driver (REST API client) for Node.js
Stars: ✭ 935 (+2650%)
Mutual labels:  neo4j, cypher
Neo4j 3d Force Graph
Experiments with Neo4j & 3d-force-graph https://github.com/vasturiano/3d-force-graph
Stars: ✭ 159 (+367.65%)
Mutual labels:  neo4j, cypher
neo4j-faker
Use faker cypher functions to generate demo and test data with cypher
Stars: ✭ 30 (-11.76%)
Mutual labels:  neo4j, cypher

Build Status

Decypher

decypher is a node.js library packing a handful of utilities to deal with cypher queries.

It includes the following:

Installation

You can install decypher from npm likewise:

npm install decypher

or from github if you need the latest development version:

npm install git+https://github.com/Yomguithereal/decypher.git

Query loader

Query files

Write one or more cypher queries per file:

File containing a single query

// Any comments...
MATCH (n)-[r]-(t)
RETURN n,r,t LIMIT 100;

File containing multiple named queries

// name: first
// Retrieve book nodes
MATCH (b:Book)
RETURN b;

// name: second
// Retrieve vocabulary nodes
MATCH (v:Vocabulary)
RETURN v;

Decyphering

Just require decypher and use it to load your queries:

var decypher = require('decypher');
// Or to only load the relevant code
var decypher = require('decypher/loader');

// Loading a single query
decypher('./single-query.cypher');
>>> 'MATCH (n)-[r]-(t)\nRETURN n,r,t LIMIT 100;'

// Loading multiple named queries
decypher('./multiple-queries.cypher');
>>> {
  first: 'MATCH (b:Book)\nRETURN b;',
  second: 'MATCH (v:Vocabulary)\nRETURN v;'
}

// Loading a batch of files at once
decypher({
  single: './single-query.cypher',
  multiple: './multiple-queries.cypher'
});
>>> {
  single: 'MATCH (n)-[r]-(t)\nRETURN n,r,t LIMIT 100;',
  multiple: {
    first: 'MATCH (b:Book)\nRETURN b;',
    second: 'MATCH (v:Vocabulary)\nRETURN v;'
  }
}

// Loading the content of a folder

// folder/
//   - single.cypher
//   - multiple.cypher
decypher('./folder');
>>> {
  single: 'MATCH (n)-[r]-(t)\nRETURN n,r,t LIMIT 100;',
  multiple: {
    first: 'MATCH (b:Book)\nRETURN b;',
    second: 'MATCH (v:Vocabulary)\nRETURN v;'
  }
}

// Choosing a different extension when loading a folder
decypher('./path-to-queries-folder', 'cql');

Now that if what you want is only to parse cypher strings because you retrieved the files on your, own, you can alternatively use decypher.parse.

Query builder

Note that this query builder is widely inspired by the query-builder package by @shesek but fixed and updated to support cypher's latest evolutions.

The result object of the builder is also made to match @thingdom node-neo4j specifications for the db.cypher method.

var Query = require('decypher').Query;
// Or to only load the relevant code
var Query = require('decypher/query');

// Creating a query
var cypher = new Query()
  .match('MATCH (n:Node)')
  .where('n.title = {title}', {title: 'The best title'})
  .return('n');

// Compiling to string
cypher.compile();
// or
cypher.toString();
>>> `MATCH (n:Node)
     WHERE n.title = {title}
     RETURN n;`

// Retrieving the query's parameters
cypher.params();
>>> {
  title: 'The best title'
}

// Retrieving the query's statements as an array
cypher.statements();
>>> [
  'MATCH (n:Node)',
  'WHERE n.title = {title}',
  'RETURN n'
]

// Retrieving all of the above at once
var {query, params, statements} = cypher.build();

// You can also alternatively interpolate the params into the query
// (Useful for debugging but unsafe!!!)
cypher.interpolate();
>>> `MATCH (n:Node)
     WHERE n.title = "The best title"
     RETURN n;`

// Note that multi words statements like `ORDER BY` have to be written in camel-case:
cypher.orderBy('n.title');

// You can also set a bunch of params at once
cypher.params({whatever: 'is needed'});
cypher.param('whatever', 'is needed');

// If you need to pass multiple query parts at once & separated by a comma
// just pass an array of strings instead of a single string.
cypher.create(['(a:Actor)', '(m:Movie)']);
>>> 'CREATE (a:Actor), (m:Movie)'

// You can also add arbitrary parts to the query if required
cypher.add('anything you want');
cypher.add('with {param}', {param: 'heart'});

// It's possible to directly pass an expression to the query builder:
cypher.where(Expression('a').or('b'));
>>> 'WHERE a OR b'

// It's also possible to pass a descriptive object that will build a
// relationship pattern using the `helpers.relationshipPattern` function:
cypher.match({source: 'a', target: 'b', identifier: 'r', direction: 'out'});
>>> 'MATCH (a)-[r]->(b)'

// Finally, you can segment your query for convenience
var cypher = new Query(),
    start = cypher.segment(),
    end = cypher.segment();

end.return('a');
start.match('(a:Actor)');

cypher.compile();
>>> `MATCH (a:Actor)
     RETURN a;`

Special cases

FOREACH

query.foreach(
  'name IN {names}',
  'CREATE (c:Person, {name: name})',
  {names: ['John', 'Elizabeth']}
);

// Using a sub query (params will be merged into the main query)
var subquery = new Query();
subquery.create('(c:Person, {name: name})');
query.foreach('name IN names', subquery, {names: [...]});

Expression builder

The expression builder lets you build where expression easily:

var Expression = require('decypher').Expression;
// Or to only load the relevant code
var Expression = require('decypher/expression');

var expr = new Expression('a = b');
expr.and('c = d');

expr.compile();
// or
expr.toString();
>>> 'a = b AND c = d'

// Note that you can nest expressions:
var expr = new Expression('a = b');
expr
  .or(Expression('c = d').and('e = f'));

expr.compile();
>>> 'a = b OR (c = d AND e = f)'

expr.isEmpty();
>>> false

Note that expressions can be directly fed to the Query builder.

Helpers

Escaping identifiers

var helpers = require('decypher').helpers;
// Or to only load the relevant code
var helpers = require('decypher/helpers');

helpers.escapeIdentifier('Complex `Identifier`');
>>> '`Complex ``Identifier```'

Escaping literal maps

var helpers = require('decypher').helpers;
// Or to only load the relevant code
var helpers = require('decypher/helpers');

helpers.escapeLiteralMap({
  hello: 'world',
  'complex key': 3
});
>>> '{hello: "world", `complex key`: 3}'

// Indicating parameter keys
helpers.escapeLiteralMap({
  name: 'name',
  number: 2
}, ['name']);
>>> '{name: {name}, number: 2}'

Building node patterns

var helpers = require('decypher').helpers;
// Or to only load the relevant code
var helpers = require('decypher/helpers');

// Possible options are:
//   * `identifier`: a string
//   * `label` or `labels`: a string or an array of strings
//   * `data`:
//       - if string, will produce a single parameter
//       - if object, will stringify it
//   * `paramKeys`: will be passed to escapeLiteralMap when stringifying data

helpers.nodePattern();
>>> '()'

helpers.nodePattern('n');
>>> '(n)'

helpers.nodePattern({
  identifier: 'n',
  label: 'Node'
});
>>> '(n:Node)'

helpers.nodePattern({
  label: 'Node',
  data: {title: 'Hello'}
});
>>> '(n:Node {title: "Hello"})'

helpers.nodePattern({
  identifier: 'n',
  data: 'paramName'
});
>>> '(n {paramName})'

helpers.nodePattern({
  label: 'Chapter',
  data: {title: 'title'},
  paramKeys: ['title']
});
>>> '(:Chapter {title: {title}})'

Building relationship patterns

var helpers = require('decypher').helpers;
// Or to only load the relevant code
var helpers = require('decypher/helpers');

// Possible options are:
//   * `direction`: "in" or "out"
//   * `identifier`: a string
//   * `type` or `types`: a string or an array of strings
//   * `data`:
//       - if string, will produce a single parameter
//       - if object, will stringify it
//   * `paramKeys`: will be passed to escapeLiteralMap when stringifying data
//   * `source`: the source node (passed to the `nodePattern` function)
//   * `target`: the target node (passed to the `nodePattern` function)

helpers.relationshipPattern();
>>> '--'

helpers.relationshipPattern('r');
>>> '-[r]-'

helpers.relationshipPattern({
  direction: 'out',
  identifier: 'r',
  type: 'KNOWS'
});
>>> '-[r:KNOWS]->'

helpers.relationshipPattern({
  direction: 'in',
  types: ['PLAYS_IN', 'KNOWS']
});
>>> '<-[:PLAYS_IN|:KNOWS]-'

helpers.relationshipPattern({
  direction: 'in',
  identifier: 'r',
  data: 'paramName'
});
>>> '<-[r {paramName}]-'

helpers.relationshipPattern({
  type: 'KNOWS',
  data: {since: 1975}
});
>>> '-[:KNOWS {since: 1975}]-'

helpers.relationshipPattern({
  direction: 'out',
  type: 'PLAYED_IN',
  source: 'a',
  target: {
    identifier: 'm',
    label: 'Movie'
  }
});
>>> '(a)-[:PLAYED_IN]->(m:Movie)'

Building search patterns

Note that it will escape for query for regular expression use through the escape-regexp module.

var helpers = require('decypher').helpers;
// Or to only load the relevant code
var helpers = require('decypher/helpers');

// Possible options are:
//   * `flags` [`'ius'`]: Flags for the regular expression.
//   * `partial` [`true`]: Should the match be partial (wrapped in `.*query.*`)?

helpers.searchPattern('john');
>>> '(?ius).*john.*'

helpers.searchPattern('john', {flags: 'im'});
>>> '(?im).*john.*'

helpers.searchPattern('john', {flags: null, partial: false});
>>> 'john'

Contribution

Contributions are of course more than welcome. Be sure to add and pass any relevant unit tests before submitting any code.

git clone [email protected]:Yomguithereal/decypher.git
cd decypher

# Installing dependencies
npm install

# Running unit tests
npm test

Roadmap

  • Some helpers
  • A batch

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].