Add tutorial articles to docs/user_technical

Summary:
Quick start summary:
  - Quick Start
  -- Installation
  --- Debian Package Installation
  --- RPM Package Installation
  --- Docker Installation
  ---- Note about Named Volumes
  ---- Note for OS X/macOS users
  -- Querying
  --- Supported Languages
  -- Telemetry
  -- Where to Next

Example (TED/football/europe) summary:
  - Article Name
  -- Introduction
  -- Data Model
  -- Importing the Snapshot
  -- Example Queries

Programmatic Querying summary:
  - Programmatic Querying
  -- Supported Languages
  -- Secure Sockets Layer (SSL)
  -- Examples
  --- Python Example
  --- Java Example
  --- JavaScript Example
  --- C# Example
  -- Limitations
  --- Multiple Users & Authorization

Reviewers: buda, dtomicevic, teon.banek, mtomic

Reviewed By: buda, teon.banek

Differential Revision: https://phabricator.memgraph.io/D1516
This commit is contained in:
Ivan Paljak 2018-08-02 13:56:21 +02:00
parent 4d3c0a2fa5
commit da89dcb3ee
5 changed files with 1059 additions and 0 deletions

View File

@ -0,0 +1,176 @@
## Analyzing TED Talks
This article is a part of a series intended to show users how to use Memgraph
on real-world data and, by doing so, retrieve some interesting and useful
information.
We highly recommend checking out the other articles from this series:
* [Exploring the European Road Network](tutorial__exploring_the_european_road_network.md)
* [Graphing the Premier League](tutorial__graphing_the_premier_league.md)
### Introduction
[TED](https://www.ted.com/) is a nonprofit organization devoted to spreading
ideas, usually in the form of short, powerful talks.
Today, TED talks are influential videos from expert speakers on almost all
topics — from science to business to global issues.
Here we present a small dataset which consists of 97 talks, show how to model
this data as a graph and demonstrate a few example queries.
### Data Model
Each TED talk has a main speaker, so we
identify two types of nodes — `Talk` and `Speaker`. Also, we will add
an edge of type `Gave` pointing to a `Talk` from its main `Speaker`.
Each speaker has a name so we can add property `name` to `Speaker` node.
Likewise, we'll add properties `name`, `title` and `description` to node
`Talk`. Furthermore, each talk is given in a specific TED event, so we can
create node `Event` with property `name` and relationship `InEvent` between
talk and event.
Talks are tagged with keywords to facilitate searching, hence we
add node `Tag` with property `name` and relationship `HasTag` between talk and
tag. Moreover, users give ratings to each talk by selecting up to three
predefined string values. Therefore we add node `Rating` with these values as
property `name` and relationship`HasRating` with property `user_count` between
talk and rating nodes.
### Importing the Snapshot
We have prepared a database snapshot for this example, so the user can easily
import it when starting Memgraph using the `--durability-directory` option.
```bash
/usr/lib/memgraph/memgraph --durability-directory /usr/share/memgraph/examples/TEDTalk \
--durability-enabled=false --snapshot-on-exit=false
```
When using Memgraph installed from DEB or RPM package, the currently running
Memgraph server may need to be stopped before importing the example. The user
can do so using the following command:
```bash
systemctl stop memgraph
```
When using Docker, the example can be imported with the following command:
```bash
docker run -p 7687:7687 \
-v mg_lib:/var/lib/memgraph -v mg_log:/var/log/memgraph -v mg_etc:/etc/memgraph \
memgraph --durability-directory /usr/share/memgraph/examples/TEDTalk \
--durability-enabled=false --snapshot-on-exit=false
```
The user should note that any modifications of the database state will persist
only during this run of Memgraph.
### Example Queries
1) Find all talks given by specific speaker:
```opencypher
MATCH (n:Speaker {name: "Hans Rosling"})-[:Gave]->(m:Talk)
RETURN m.title;
```
2) Find the top 20 speakers with most talks given:
```opencypher
MATCH (n:Speaker)-[:Gave]->(m)
RETURN n.name, COUNT(m) AS TalksGiven
ORDER BY TalksGiven DESC LIMIT 20;
```
3) Find talks related by tag to specific talk and count them:
```opencypher
MATCH (n:Talk {name: "Michael Green: Why we should build wooden skyscrapers"})
-[:HasTag]->(t:Tag)<-[:HasTag]-(m:Talk)
WITH * ORDER BY m.name
RETURN t.name, COLLECT(m.name), COUNT(m) AS TalksCount
ORDER BY TalksCount DESC;
```
4) Find 20 most frequently used tags:
```opencypher
MATCH (t:Tag)<-[:HasTag]-(n:Talk)
RETURN t.name AS Tag, COUNT(n) AS TalksCount
ORDER BY TalksCount DESC, Tag LIMIT 20;
```
5) Find 20 talks most rated as "Funny". If you want to query by other ratings,
possible values are: Obnoxious, Jaw-dropping, OK, Persuasive, Beautiful,
Confusing, Longwinded, Unconvincing, Fascinating, Ingenious, Courageous, Funny,
Informative and Inspiring.
```opencypher
MATCH (r:Rating{name:"Funny"})<-[e:HasRating]-(m:Talk)
RETURN m.name, e.user_count ORDER BY e.user_count DESC LIMIT 20;
```
6) Find inspiring talks and their speakers from the field of technology:
```opencypher
MATCH (n:Talk)-[:HasTag]->(m:Tag {name: "technology"})
MATCH (n)-[r:HasRating]->(p:Rating {name: "Inspiring"})
MATCH (n)<-[:Gave]-(s:Speaker)
WHERE r.user_count > 1000
RETURN n.title, s.name, r.user_count ORDER BY r.user_count DESC;
```
7) Now let's see one real-world example &mdash; how to make a real-time
recommendation. If you've just watched a talk from a certain
speaker (e.g. Hans Rosling) you might be interested in finding more talks from
the same speaker on a similar topic:
```opencypher
MATCH (n:Speaker {name: "Hans Rosling"})-[:Gave]->(m:Talk)
MATCH (t:Talk {title: "New insights on poverty"})-[:HasTag]->(tag:Tag)<-[:HasTag]-(m)
WITH * ORDER BY tag.name
RETURN m.title as Title, COLLECT(tag.name), COUNT(tag) as TagCount
ORDER BY TagCount DESC, Title;
```
The following few queries are focused on extracting information about
TED events.
8) Find how many talks were given per event:
```opencypher
MATCH (n:Event)<-[:InEvent]-(t:Talk)
RETURN n.name as Event, COUNT(t) AS TalksCount
ORDER BY TalksCount DESC, Event
LIMIT 20;
```
9) Find the most popular tags in the specific event:
```opencypher
MATCH (n:Event {name:"TED2006"})<-[:InEvent]-(t:Talk)-[:HasTag]->(tag:Tag)
RETURN tag.name as Tag, COUNT(t) AS TalksCount
ORDER BY TalksCount DESC, Tag
LIMIT 20;
```
10) Discover which speakers participated in more than 2 events:
```opencypher
MATCH (n:Speaker)-[:Gave]->(t:Talk)-[:InEvent]->(e:Event)
WITH n, COUNT(e) AS EventsCount WHERE EventsCount > 2
RETURN n.name as Speaker, EventsCount
ORDER BY EventsCount DESC, Speaker;
```
11) For each speaker search for other speakers that participated in same
events:
```opencypher
MATCH (n:Speaker)-[:Gave]->()-[:InEvent]->(e:Event)<-[:InEvent]-()<-[:Gave]-(m:Speaker)
WHERE n.name != m.name
WITH DISTINCT n, m ORDER BY m.name
RETURN n.name AS Speaker, COLLECT(m.name) AS Others
ORDER BY Speaker;
```

View File

@ -0,0 +1,178 @@
## Exploring the European Road Network
This article is a part of a series intended to show users how to use Memgraph
on real-world data and, by doing so, retrieve some interesting and useful
information.
We highly recommend checking out the other articles from this series:
* [Analyzing TED Talks](tutorial__analyzing_ted_talks.md)
* [Graphing the Premier League](tutorial__graphing_the_premier_league.md)
### Introduction
This particular article outlines how to use some of Memgraph's built-in graph
algorithms. More specifically, the article shows how to use breadth-first search
graph traversal algorithm, and Dijkstra's algorithm for finding weighted
shortest paths between nodes in the graph.
### Data model
One of the most common applications of graph traversal algorithms is driving
route computation, so we will use European road network graph as an example.
The graph consists of 999 major European cities from 39 countries in total.
Each city is connected to the country it belongs to via an edge of type `:In_`.
There are edges of type `:Road` connecting cities less than 500 kilometers
apart. Distance between cities is specified in the `length` property of the
edge.
### Importing the Snapshot
We have prepared a database snapshot for this example, so the user can easily
import it when starting Memgraph using the `--durability-directory` option.
```bash
/usr/lib/memgraph/memgraph --durability-directory /usr/share/memgraph/examples/Europe \
--durability-enabled=false --snapshot-on-exit=false
```
When using Memgraph installed from DEB or RPM package, the currently running
Memgraph server may need to be stopped before importing the example. The user
can do so using the following command:
```bash
systemctl stop memgraph
```
When using Docker, the example can be imported with the following command:
```bash
docker run -p 7687:7687 \
-v mg_lib:/var/lib/memgraph -v mg_log:/var/log/memgraph -v mg_etc:/etc/memgraph \
memgraph --durability-directory /usr/share/memgraph/examples/Europe \
--durability-enabled=false --snapshot-on-exit=false
```
The user should note that any modifications of the database state will persist
only during this run of Memgraph.
### Example Queries
1) Let's list all of the countries in our road network.
```opencypher
MATCH (c:Country) RETURN c.name ORDER BY c.name;
```
2) Which Croatian cities are in our road network?
```opencypher
MATCH (c:City)-[:In_]->(:Country {name: "Croatia"})
RETURN c.name ORDER BY c.name;
```
3) Which cities in our road network are less than 200 km away from Zagreb?
```opencypher
MATCH (:City {name: "Zagreb"})-[r:Road]->(c:City)
WHERE r.length < 200
RETURN c.name ORDER BY c.name;
```
Now let's try some queries using Memgraph's graph traversal capabilities.
4) Say you want to drive from Zagreb to Paris. You might wonder, what is the
least number of cities you have to visit if you don't want to drive more than
500 kilometers between stops. Since the edges in our road network don't connect
cities that are more than 500 km apart, this is a great use case for the
breadth-first search (BFS) algorithm.
```opencypher
MATCH p = (:City {name: "Zagreb"})
-[:Road * bfs]->
(:City {name: "Paris"})
RETURN nodes(p);
```
5) What if we want to bike to Paris instead of driving? It is unreasonable (and
dangerous!) to bike 500 km per day. Let's limit ourselves to biking no more
than 200 km in one go.
```opencypher
MATCH p = (:City {name: "Zagreb"})
-[:Road * bfs (e, v | e.length <= 200)]->
(:City {name: "Paris"})
RETURN nodes(p);
```
"What is this special syntax?", you might wonder.
`(e, v | e.length <= 200)` is called a *filter lambda*. It's a function that
takes an edge symbol `e` and a vertex symbol `v` and decides whether this edge
and vertex pair should be considered valid in breadth-first expansion by
returning true or false (or Null). In the above example, lambda is returning
true if edge length is not greater than 200, because we don't want to bike more
than 200 km in one go.
6) Let's say we also don't want to visit Vienna on our way to Paris, because we
have a lot of friends there and visiting all of them would take up a lot of our
time. We just have to update our filter lambda.
```opencypher
MATCH p = (:City {name: "Zagreb"})
-[:Road * bfs (e, v | e.length <= 200 AND v.name != "Vienna")]->
(:City {name: "Paris"})
RETURN nodes(p);
```
As you can see, without the additional restriction we could visit 11 cities. If
we want to avoid Vienna, we must visit at least 12 cities.
7) Instead of counting the cities visited, we might want to find the shortest
paths in terms of distance travelled. This is a textbook application of
Dijkstra's algorithm. The following query will return the list of cities on the
shortest path from Zagreb to Paris along with the total length of the path.
```opencypher
MATCH p = (:City {name: "Zagreb"})
-[:Road * wShortest (e, v | e.length) total_weight]->
(:City {name: "Paris"})
RETURN nodes(p) as cities, total_weight;
```
As you can see, the syntax is quite similar to breadth-first search syntax.
Instead of a filter lambda, we need to provide a *weight lambda* and the *total
weight symbol*. Given an edge and vertex pair, weight lambda must return the
cost of expanding to the given vertex using the given edge. The path returned
will have the smallest possible sum of costs and it will be stored in the total
weight symbol. A limitation of Dijkstra's algorithm is that the cost must be
non-negative.
8) We can also combine weight and filter lambdas in the shortest-path query.
Let's say we're interested in the shortest path that doesn't require travelling
more that 200 km in one go for our bike route.
```opencypher
MATCH p = (:City {name: "Zagreb"})
-[:Road * wShortest (e, v | e.length) total_weight (e, v | e.length <= 200)]->
(:City {name: "Paris"})
RETURN nodes(p) as cities, total_weight;
```
9) Let's try and find 10 cities that are furthest away from Zagreb.
```opencypher
MATCH (:City {name: "Zagreb"})
-[:Road * wShortest (e, v | e.length) total_weight]->
(c:City)
RETURN c, total_weight
ORDER BY total_weight DESC LIMIT 10;
```
It is not surprising to see that they are all in Siberia.
To learn more about these algorithms, we suggest you check out their Wikipedia
pages:
* [Breadth-first search](https://en.wikipedia.org/wiki/Breadth-first_search)
* [Dijkstra's algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)

View File

@ -0,0 +1,190 @@
## Graphing the Premier League
This article is a part of a series intended to show users how to use Memgraph
on real-world data and, by doing so, retrieve some interesting and useful
information.
We highly recommend checking out the other articles from this series:
* [Analyzing TED Talks](tutorial__analyzing_ted_talks.md)
* [Exploring the European Road Network](tutorial__exploring_the_european_road_network.md)
### Introduction
[Football](https://en.wikipedia.org/wiki/Association_football)
is a team sport played between two teams of eleven
players with a spherical ball. The game is played on a rectangular pitch with
a goal at each and. The object of the game is to score by moving the ball
beyond the goal line into the opposing goal. The game is played by more than
250 million players in over 200 countries, making it the world's most
popular sport.
In this article, we will present a graph model of a reasonably sized dataset
of football matches across world's most popular leagues.
### Data Model
In essence, we are trying to model a set of football matches. All information
about a single match is going to be contained in three nodes and two edges.
Two of the nodes will represent the teams that have played the match, while the
third node will represent the game itself. Both edges are directed from the
team nodes to the game node and are labeled as `:Played`.
Let us consider a real life example of this model&mdash;Arsene Wenger's 1000th
game in charge of Arsenal. This was a regular fixture of a 2013/2014
English Premier League, yet it was written in the stars that this historic
moment would be a big London derby against Chelsea on Stanford Bridge. The
sketch below shows how this game is being modeled in our database.
```
+---------------+ +-----------------------------+
|n: Team | |w: Game |
| |-[:Played {side: "home", outcome: "won"}]-->| |
|name: "Chelsea"| |HT_home_score: 4 |
+---------------+ |HT_away_score: 0 |
|HT_result: "H" |
|FT_home_score: 6 |
|FT_away_score: 0 |
|FT_result: "H" |
+---------------+ |date: "2014-03-22" |
|m: Team | |league: "ENG-Premier League" |
| |-[:Played {side: "away", outcome: "lost"}]->|season: 2013 |
|name: "Arsenal"| |referee: "Andre Marriner" |
+---------------+ +-----------------------------+
```
### Importing the Snapshot
We have prepared a database snapshot for this example, so the user can easily
import it when starting Memgraph using the `--durability-directory` option.
```bash
/usr/lib/memgraph/memgraph --durability-directory /usr/share/memgraph/examples/football \
--durability-enabled=false --snapshot-on-exit=false
```
When using Memgraph installed from DEB or RPM package, the currently running
Memgraph server may need to be stopped before importing the example. The user
can do so using the following command:
```bash
systemctl stop memgraph
```
When using Docker, the example can be imported with the following command:
```bash
docker run -p 7687:7687 \
-v mg_lib:/var/lib/memgraph -v mg_log:/var/log/memgraph -v mg_etc:/etc/memgraph \
memgraph --durability-directory /usr/share/memgraph/examples/football \
--durability-enabled=false --snapshot-on-exit=false
```
The user should note that any modifications of the database state will persist
only during this run of Memgraph.
### Example Queries
1) You might wonder, what leagues are supported?
```opencypher
MATCH (n:Game)
RETURN DISTINCT n.league AS League
ORDER BY League;
```
2) We have stored a certain number of seasons for each league. What is the
oldest/newest season we have included?
```opencypher
MATCH (n:Game)
RETURN DISTINCT n.league AS League, MIN(n.season) AS Oldest, MAX(n.season) AS Newest
ORDER BY League;
```
3) You have already seen one game between Chelsea and Arsenal, let's list all of
them in chronological order.
```opencypher
MATCH (n:Team {name: "Chelsea"})-[e:Played]->(w:Game)<-[f:Played]-(m:Team {name: "Arsenal"})
RETURN w.date AS Date, e.side AS Chelsea, f.side AS Arsenal,
w.FT_home_score AS home_score, w.FT_away_score AS away_score
ORDER BY Date;
```
4) How about filtering games in which Chelsea won?
```opencypher
MATCH (n:Team {name: "Chelsea"})-[e:Played {outcome: "won"}]->
(w:Game)<-[f:Played]-(m:Team {name: "Arsenal"})
RETURN w.date AS Date, e.side AS Chelsea, f.side AS Arsenal,
w.FT_home_score AS home_score, w.FT_away_score AS away_score
ORDER BY Date;
```
5) Home field advantage is a thing in football. Let's list the number of home
defeats for each Premier League team in the 2016/2017 season.
```opencypher
MATCH (n:Team)-[:Played {side: "home", outcome: "lost"}]->
(w:Game {league: "ENG-Premier League", season: 2016})
RETURN n.name AS Team, count(w) AS home_defeats
ORDER BY home_defeats, Team;
```
6) At the end of the season the team with the most points wins the league. For
each victory, a team is awarded 3 points and for each draw it is awarded
1 point. Let's find out how many points did reigning champions (Chelsea) have
at the end of 2016/2017 season.
```opencypher
MATCH (n:Team {name: "Chelsea"})-[:Played {outcome: "drew"}]->(w:Game {season: 2016})
WITH n, COUNT(w) AS draw_points
MATCH (n)-[:Played {outcome: "won"}]->(w:Game {season: 2016})
RETURN draw_points + 3 * COUNT(w) AS total_points;
```
7) In fact, why not retrieve the whole table?
```opencypher
MATCH (n)-[:Played {outcome: "drew"}]->(w:Game {league: "ENG-Premier League", season: 2016})
WITH n, COUNT(w) AS draw_points
MATCH (n)-[:Played {outcome: "won"}]->(w:Game {league: "ENG-Premier League", season: 2016})
RETURN n.name AS Team, draw_points + 3 * COUNT(w) AS total_points
ORDER BY total_points DESC;
```
8) People have always debated which of the major leagues is the most exciting.
One basic metric is the average number of goals per game. Let's see the results
at the end of the 2016/2017 season. WARNING: This might shock you.
```opencypher
MATCH (w:Game {season: 2016})
RETURN w.league, AVG(w.FT_home_score) + AVG(w.FT_away_score) AS avg_goals_per_game
ORDER BY avg_goals_per_game DESC;
```
9) Another metric might be the number of comebacks&mdash;games where one side
was winning at half time but were overthrown by the other side by the end
of the match. Let's count such occurrences during all supported seasons across
all supported leagues.
```opencypher
MATCH (g:Game) WHERE
(g.HT_result = "H" AND g.FT_result = "A") OR
(g.HT_result = "A" AND g.FT_result = "H")
RETURN g.league AS League, count(g) AS Comebacks
ORDER BY Comebacks DESC;
```
10) Exciting leagues also tend to be very unpredictable. On that note, let's
list all triplets of teams where, during the course of one season, team A won
against team B, team B won against team C and team C won against team A.
```opencypher
MATCH (a)-[:Played {outcome: "won"}]->(p:Game {league: "ENG-Premier League", season: 2016})<--
(b)-[:Played {outcome: "won"}]->(q:Game {league: "ENG-Premier League", season: 2016})<--
(c)-[:Played {outcome: "won"}]->(r:Game {league: "ENG-Premier League", season: 2016})<--(a)
WHERE p.date < q.date AND q.date < r.date
RETURN a.name AS Team1, b.name AS Team2, c.name AS Team3;
```

View File

@ -0,0 +1,224 @@
## Programmatic Querying
### Supported Languages
If users wish to query Memgraph programmatically, they can do so using the
[Bolt protocol](https://boltprotocol.org). Bolt was designed for efficient
communication with graph databases and Memgraph supports
[Version 1](https://boltprotocol.org/v1) of the protocol. Bolt protocol drivers
for some popular programming languages are listed below:
* [Java](https://github.com/neo4j/neo4j-java-driver)
* [Python](https://github.com/neo4j/neo4j-python-driver)
* [JavaScript](https://github.com/neo4j/neo4j-javascript-driver)
* [C#](https://github.com/neo4j/neo4j-dotnet-driver)
* [Ruby](https://github.com/neo4jrb/neo4j)
* [Haskell](https://github.com/zmactep/hasbolt)
* [PHP](https://github.com/graphaware/neo4j-bolt-php)
### Secure Sockets Layer (SSL)
Secure connections are supported and enabled by default. The server initially
ships with a self-signed testing certificate. The certificate can be replaced
by editing the following parameters in `/etc/memgraph/memgraph.conf`:
```
--cert-file=/path/to/ssl/certificate.pem
--key-file=/path/to/ssl/privatekey.pem
```
To disable SSL support and use insecure connections to the database you should
set both parameters (`--cert-file` and `--key-file`) to empty values.
### Examples
In this article we have included some basic usage examples for the following
supported languages:
* [Python](#python-example)
* [Java](#java-example)
* [JavaScript](#javascript-example)
* [C#](#c-sharp-example)
Examples for the languages listed above are equivalent.
#### Python Example
Neo4j officially supports Python for interacting with an openCypher and Bolt
compliant database. For details consult the
[official documentation](http://neo4j.com/docs/api/python-driver) and the
[GitHub project](https://github.com/neo4j/neo4j-python-driver).
The code snippet below outlines a basic usage example which connects to the
database and executes a couple of elementary queries.
```python
from neo4j.v1 import GraphDatabase, basic_auth
# Initialize and configure the driver.
# * provide the correct URL where Memgraph is reachable;
# * use an empty user name and password.
driver = GraphDatabase.driver("bolt://localhost:7687",
auth=basic_auth("", ""))
# Start a session in which queries are executed.
session = driver.session()
# Execute openCypher queries.
# After each query, call either `consume()` or `data()`
session.run('CREATE (alice:Person {name: "Alice", age: 22})').consume()
# Get all the vertices from the database (potentially multiple rows).
vertices = session.run('MATCH (n) RETURN n').data()
# Assuming we started with an empty database, we should have Alice
# as the only row in the results.
only_row = vertices.pop()
alice = only_row["n"]
# Print out what we retrieved.
print("Found a vertex with labels '{}', name '{}' and age {}".format(
alice['name'], alice.labels, alice['age'])
# Remove all the data from the database.
session.run('MATCH (n) DETACH DELETE n').consume()
# Close the session and the driver.
session.close()
driver.close()
```
#### Java Example
The details about Java driver can be found on
[GitHub](https://github.com/neo4j/neo4j-java-driver).
The code snippet below outlines a basic usage example which connects to the
database and executes a couple of elementary queries.
```java
import org.neo4j.driver.v1.*;
import org.neo4j.driver.v1.types.*;
import static org.neo4j.driver.v1.Values.parameters;
import java.util.*;
public class JavaQuickStart {
public static void main(String[] args) {
// Initialize driver.
Config config = Config.build().toConfig();
Driver driver = GraphDatabase.driver("bolt://localhost:7687",
AuthTokens.basic("",""),
config);
// Execute basic queries.
try (Session session = driver.session()) {
StatementResult rs1 = session.run("MATCH (n) DETACH DELETE n");
StatementResult rs2 = session.run(
"CREATE (alice: Person {name: 'Alice', age: 22})");
StatementResult rs3 = session.run( "MATCH (n) RETURN n");
List<Record> records = rs3.list();
Record record = records.get(0);
Node node = record.get("n").asNode();
System.out.println(node.get("name").asString());
} catch (Exception e) {
System.out.println(e);
System.exit(1);
}
// Cleanup.
driver.close();
}
}
```
#### JavaScript Example
The details about Javascript driver can be found on
[GitHub](https://github.com/neo4j/neo4j-javascript-driver).
Here is an example related to `Node.js`. Memgraph doesn't have integrated
support for `WebSocket` which is required during the execution in any web
browser. If you want to run `openCypher` queries from a web browser,
[websockify](https://github.com/novnc/websockify) has to be up and running.
Requests from web browsers are wrapped into `WebSocket` messages, and a proxy
is needed to handle the overhead. The proxy has to be configured to point out
to Memgraph's Bolt port and web browser driver has to send requests to the
proxy port.
The code snippet below outlines a basic usage example which connects to the
database and executes a couple of elementary queries.
```javascript
var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver("bolt://localhost:7687",
neo4j.auth.basic("neo4j", "1234"));
var session = driver.session();
function die() {
session.close();
driver.close();
}
function run_query(query, callback) {
var run = session.run(query, {});
run.then(callback).catch(function (error) {
console.log(error);
die();
});
}
run_query("MATCH (n) DETACH DELETE n", function (result) {
console.log("Database cleared.");
run_query("CREATE (alice: Person {name: 'Alice', age: 22})", function (result) {
console.log("Record created.");
run_query("MATCH (n) RETURN n", function (result) {
console.log("Record matched.");
var alice = result.records[0].get("n");
console.log(alice.labels[0]);
console.log(alice.properties["name"]);
session.close();
driver.close();
});
});
});
```
#### C# Example {#c-sharp-example}
The details about C# driver can be found on
[GitHub](https://github.com/neo4j/neo4j-dotnet-driver).
The code snipped below outlines a basic usage example which connects to the
database and executes a couple of elementary queries.
```csh
using System;
using System.Linq;
using Neo4j.Driver.V1;
public class Basic {
public static void Main(string[] args) {
// Initialize the driver.
var config = Config.DefaultConfig;
using(var driver = GraphDatabase.Driver("bolt://localhost:7687", AuthTokens.None, config))
using(var session = driver.Session())
{
// Run basic queries.
session.Run("MATCH (n) DETACH DELETE n").Consume();
session.Run("CREATE (alice:Person {name: \"Alice\", age: 22})").Consume();
var result = session.Run("MATCH (n) RETURN n").First();
var alice = (INode) result["n"];
Console.WriteLine(alice["name"]);
Console.WriteLine(string.Join(", ", alice.Labels));
Console.WriteLine(alice["age"]);
}
Console.WriteLine("All ok!");
}
}
```
### Limitations
Memgraph is currently in an early stage, and therefore has certain limitations
we plan to remove in future versions.
#### Multiple Users & Authorization
At the moment, Memgraph is single-user only and there is no way to control user
privileges, meaning that the default user has read and write privileges over
the whole database.

View File

@ -0,0 +1,291 @@
## Quick Start {#tutorial-quick-start}
This article briefly outlines the basic steps necessary to install and run
Memgraph. It also gives a brief glimpse into the world of OpenCypher and
outlines some information on programmatic querying of Memgraph. The users
should also make sure to read and fully understand the implications of
[telemetry](#telemetry) at the very end of the article.
### Installation
With regards to their own preference, users can download the Memgraph binary
as:
* [a Debian package for Debian 9 (Stretch)](#debian-installation)
* [a RPM package for CentOS 7](#RPM-installation)
* [a Docker image](#docker-installation)
After downloading the binary, users are advised to proceed to the corresponding
section below which outlines the installation details.
It is important to note that newer versions of Memgraph are currently not
backward compatible with older versions. This is mainly noticeable by
being unable to load storage snapshots between different versions.
#### Debian Package Installation {#debian-installation}
After downloading Memgraph as a Debian package, install it by running the
following:
```bash
dpkg -i /path/to/memgraph_<version>.deb
```
On successful installation, Memgraph should already be running. To
make sure that is true, user can start it explicitly with the command:
```bash
systemctl start memgraph
```
To verify that Memgraph is running, user can run the following command:
```bash
journalctl --unit memgraph
```
If successful, the user should receive an output similar to the following:
```bash
Nov 23 13:40:13 hostname memgraph[14654]: Starting 8 BoltS workers
Nov 23 13:40:13 hostname memgraph[14654]: BoltS server is fully armed and operational
Nov 23 13:40:13 hostname memgraph[14654]: BoltS listening on 0.0.0.0 at 7687
```
At this point, Memgraph is ready to process queries. To try out some elementary
queries, the user should proceed to [querying](#querying) section of this
article.
To shut down the Memgraph server, issue the following command:
```bash
systemctl stop memgraph
```
Memgraph configuration is available in `/etc/memgraph/memgraph.conf`. If the
configuration is altered, Memgraph needs to be restarted.
#### RPM Package Installation {#RPM-installation}
After downloading the RPM package of Memgraph, the user can install it by
issuing the following command:
```bash
rpm -U /path/to/memgraph-<version>.rpm
```
After the successful installation, Memgraph can be started as a service. To do
so, the user can type the following command:
```bash
systemctl start memgraph
```
To verify that Memgraph is running, the user should run the following command:
```bash
journalctl --unit memgraph
```
If successful, the user should receive an output similar to the following:
```bash
Nov 23 13:40:13 hostname memgraph[14654]: Starting 8 BoltS workers
Nov 23 13:40:13 hostname memgraph[14654]: BoltS server is fully armed and operational
Nov 23 13:40:13 hostname memgraph[14654]: BoltS listening on 0.0.0.0 at 7687
```
At this point, Memgraph is ready to process queries. To try out some elementary
queries, the user should proceed to [querying](#querying) section of this
article.
To shut down the Memgraph server, issue the following command:
```bash
systemctl stop memgraph
```
Memgraph configuration is available in `/etc/memgraph/memgraph.conf`. If the
configuration is altered, Memgraph needs to be restarted.
#### Docker Installation {#docker-installation}
Before proceeding with the installation, the user should install the Docker
engine on their system. Instructions on how to install Docker can be found on
the [official Docker website](https://docs.docker.com/engine/installation).
Memgraph's Docker image was built with Docker version `1.12` and should be
compatible with all newer versions.
After successful Docker installation, the user should install the Memgraph
Docker image and import it using the following command:
```bash
docker load -i /path/to/memgraph-<version>-docker.tar.gz
```
To actually start Memgraph, the user should issue the following command:
```bash
docker run -p 7687:7687 \
-v mg_lib:/var/lib/memgraph -v mg_log:/var/log/memgraph -v mg_etc:/etc/memgraph \
memgraph
```
If successful, the user should be greeted with the following message:
```bash
Starting 8 workers
Server is fully armed and operational
Listening on 0.0.0.0 at 7687
```
At this point, Memgraph is ready to process queries. To try out some elementary
queries, the user should proceed to [querying](#querying) section of this
article.
To stop Memgraph, press `Ctrl-c`.
#### Note about named volumes
Memgraph configuration is available in Docker's named volume `mg_etc`. On
Linux systems it should be in
`/var/lib/docker/volumes/mg_etc/_data/memgraph.conf`. After changing the
configuration, Memgraph needs to be restarted.
If it happens that the named volumes are reused between different Memgraph
versions, Docker will overwrite a folder within the container with existing
data from the host machine. If a new file is introduced, or two versions of
Memgraph are not compatible, some features might not work or Memgraph might
not be able to work correctly. We strongly advise the users to use another
named volume for a different Memgraph version or to remove the existing volume
from the host with the following command:
```bash
docker volume rm <volume_name>
```
#### Note for OS X/macOS Users {#OSX-note}
Although unlikely, some OS X/macOS users might experience minor difficulties
after following the Docker installation instructions. Instead of running on
`localhost`, a Docker container for Memgraph might be running on a custom IP
address. Fortunately, that IP address can be found using the following
algorithm:
1) Find out the container ID of the Memgraph container
By issuing the command `docker ps` the user should get an output similar to the
following:
```bash
CONTAINER ID IMAGE COMMAND CREATED ...
9397623cd87e memgraph "/usr/lib/memgraph/m…" 2 seconds ago ...
```
At this point, it is important to remember the container ID of the Memgraph
image. In our case, that is `9397623cd87e`.
2) Use the container ID to retrieve an IP of the container
```bash
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 9397623cd87e
```
The command above should yield the sought IP. If that IP does not correspond to
`localhost`, it should be used instead of `localhost` when firing up the
`neo4j-client` in the [querying](#querying) section.
### Querying {#querying}
Memgraph supports the openCypher query language which has been developed by
[Neo4j](http://neo4j.com). It is a declarative language developed specifically
for interaction with graph databases which is currently going through a
vendor-independent standardization process.
The easiest way to execute openCypher queries against Memgraph is by using
Neo4j's command-line tool. The command-line `neo4j-client` can be installed as
described [on the official website](https://neo4j-client.net).
After installing `neo4j-client`, the user can connect to the running Memgraph
instance by issuing the following shell command:
```bash
neo4j-client -u "" -p "" localhost 7687
```
After the client has started it should present a command prompt similar to:
```bash
neo4j-client 2.1.3
Enter `:help` for usage hints.
Connected to 'neo4j://@localhost:7687'
neo4j>
```
At this point it is possible to execute openCypher queries on Memgraph. Each
query needs to end with the `;` (*semicolon*) character. For example:
```opencypher
CREATE (u:User {name: "Alice"})-[:Likes]->(m:Software {name: "Memgraph"});
```
The above will create 2 nodes in the database, one labeled "User" with name
"Alice" and the other labeled "Software" with name "Memgraph". It will also
create a relationship that "Alice" *likes* "Memgraph".
To find created nodes and relationships, execute the following query:
```opencypher
MATCH (u:User)-[r]->(x) RETURN u, r, x;
```
#### Supported Languages
If users wish to query Memgraph programmatically, they can do so using the
[Bolt protocol](https://boltprotocol.org). Bolt was designed for efficient
communication with graph databases and Memgraph supports
[Version 1](https://boltprotocol.org/v1) of the protocol. Bolt protocol drivers
for some popular programming languages are listed below:
* [Java](https://github.com/neo4j/neo4j-java-driver)
* [Python](https://github.com/neo4j/neo4j-python-driver)
* [JavaScript](https://github.com/neo4j/neo4j-javascript-driver)
* [C#](https://github.com/neo4j/neo4j-dotnet-driver)
* [Ruby](https://github.com/neo4jrb/neo4j)
* [Haskell](https://github.com/zmactep/hasbolt)
* [PHP](https://github.com/graphaware/neo4j-bolt-php)
We have included some basic usage examples for some of the supported languages
in the article about [programmatic querying](tutorial__programmatic_querying.md).
### Telemetry {#telemetry}
Telemetry is an automated process by which some useful data is collected at
a remote point. At Memgraph, we use telemetry for the sole purpose of improving
our product, thereby collecting some data about the machine that executes the
database (CPU, memory, OS and kernel information) as well as some data about the
database runtime (CPU usage, memory usage, vertices and edges count).
Here at Memgraph, we deeply care about the privacy of our users and do not
collect any sensitive information. If users wish to disable Memgraph's telemetry
features, they can easily do so by either altering the line in
`/etc/memgraph/memgraph.conf` that enables telemetry (`--telemetry-enabled=true`)
into `--telemetry-enabled=false`, or by including the `--telemetry-enabled=false`
as a command-line argument when running the executable.
### Where to Next
To learn more about the openCypher language, the user should visit our
[openCypher Query Language](open-cypher.md) article. For real-world examples
of how to use Memgraph, we strongly suggest reading through the following
articles:
* [Analyzing TED Talks](tutorial__analyzing_TED_talks.md)
* [Graphing the Premier League](tutorial__graphing_the_premier_league.md)
* [Exploring the European Road Network](tutorial__exploring_the_european_road_network.md)
<!--- TODO(ipaljak) Possible broken link on docs update -->
Details on what can be stored in Memgraph can be found in the article about
[Data Storage](storage.md).
We *welcome and encourage* your feedback!