diff --git a/docs/user_technical/README.md b/docs/user_technical/README.md deleted file mode 100644 index f71b0216d..000000000 --- a/docs/user_technical/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# Technical Documentation - -## About Memgraph - -Memgraph is an ACID compliant high performance transactional in-memory graph -database management system featuring highly concurrent -data structures, multi-version concurrency control and asynchronous IO. - -[//]: # (When adding a new documentation file, please add it to the list) - -## Contents - - * [About Memgraph](#about-memgraph) - * [Quick Start](01_quick-start.md) - * [Tutorials](tutorials/02_tutorials-overview.md) - * [Analysing TED Talks](tutorials/03_analyzing-TED-talks.md) - * [Graphing the Premier League](tutorials/04_graphing-the-premier-league.md) - * [Exploring the European Road Network](tutorials/05_exploring-the-european-road-network.md) - * [How to](how_to_guides/01_how-to-guides-overview.md) - * [Import Data?](how_to_guides/02_import-data.md) - * [Query Memgraph Programmatically?](how_to_guides/03_query-memgraph-programmatically.md) - * [Ingest Data Using Kafka?](how_to_guides/04_ingest-data-using-kafka.md) - * [Manage User Privileges?](how_to_guides/05_manage-user-privileges.md) - * [Concepts](concepts/01_concepts_overview.md) - * [Storage](concepts/02_storage.md) - * [Graph Algorithms](concepts/03_graph-algorithms.md) - * [Indexing](concepts/04_indexing.md) - * [Reference Guide](reference_guide/01_reference-overview.md) - * [Reading Existing Data](reference_guide/02_reading-existing-data.md) - * [Writing New Data](reference_guide/03_writing-new-data.md) - * [Reading and Writing](reference_guide/04_reading-and-writing.md) - * [Indexing](reference_guide/05_indexing.md) - * [Graph Algorithms](reference_guide/06_graph-algorithms.md) - * [Graph Streams](reference_guide/07_graph-streams.md) - * [Security](reference_guide/08_security.md) - * [Dynamic Graph Partitioner](reference_guide/09_dynamic-graph-partitioner.md) - * [Other Features](reference_guide/10_other-features.md) - * [Differences](reference_guide/11_differences.md) - * [Upcoming Features](upcoming-features.md) - -[//]: # (Nothing should go below the contents section) diff --git a/docs/user_technical/concepts/01_concepts-overview.md b/docs/user_technical/concepts/01_concepts-overview.md deleted file mode 100644 index b5a87d6b1..000000000 --- a/docs/user_technical/concepts/01_concepts-overview.md +++ /dev/null @@ -1,11 +0,0 @@ -## Concepts Overview - -Articles within the concepts section serve as an in-depth introduction into -inner workings of Memgraph. These tend to be quite technical in nature and -are recommended for advanced users and other graph database enthusiasts. - -So far we have covered the following topics: - - * [Data Storage](02_storage.md) - * [Graph Algorithms](03_graph-algorithms.md) - * [Indexing](04_indexing.md) diff --git a/docs/user_technical/concepts/02_storage.md b/docs/user_technical/concepts/02_storage.md deleted file mode 100644 index 06ea1f5ce..000000000 --- a/docs/user_technical/concepts/02_storage.md +++ /dev/null @@ -1,106 +0,0 @@ -## Durability and Data Recovery - -*Memgraph* uses two mechanisms to ensure the durability of the stored data: - - * write-ahead logging (WAL) and - * taking periodic snapshots. - -Write-ahead logging works by logging all database modifications to a file. -This ensures that all operations are done atomically and provides a trace of -steps needed to reconstruct the database state. - -Snapshots are taken periodically during the entire runtime of *Memgraph*. When -a snapshot is triggered, the whole data storage is written to disk. The -snapshot file provides a quicker way to restore the database state. - -Database recovery is done on startup from the most recently found snapshot -file. Since the snapshot may be older than the most recent update logged in -the WAL file, the recovery process will apply the remaining state changes -found in the said WAL file. - -NOTE: Snapshot and WAL files are not (currently) compatible between *Memgraph* -versions. - -Behaviour of the above mechanisms can be tweaked in the configuration file, -usually found in `/etc/memgraph/memgraph.conf`. - -In addition to the above mentioned data durability and recovery, a -snapshot file may be generated using *Memgraph's* import tools. For more -information, take a look at the [Import Tools](../how_to_guides/02_import-tools.md) -article. - -## Storable Data Types - -Since *Memgraph* is a *graph* database management system, data is stored in -the form of graph elements: nodes and edges. Each graph element can also -contain various types of data. This chapter describes which data types are -supported in *Memgraph*. - -### Node Labels & Edge Types - -Each node can have any number of labels. A label is a text value, which can be -used to *label* or group nodes according to users' desires. A user can change -labels at any time. Similarly to labels, each edge can have a type, -represented as text. Unlike nodes, which can have multiple labels or none at -all, edges *must* have exactly one edge type. Another difference to labels, is -that the edge types are set upon creation and never modified again. - -### Properties - -Nodes and edges can store various properties. These are like mappings or -tables containing property names and their accompanying values. Property names -are represented as text, while values can be of different types. Each property -name can store a single value, it is not possible to have multiple properties -with the same name on a single graph element. Naturally, the same property -names can be found across multiple graph elements. Also, there are no -restrictions on the number of properties that can be stored in a single graph -element. The only restriction is that the values must be of the supported -types. Following is a table of supported data types. - - Type | Description ------------|------------ - `Null` | Denotes that the property has no value. This is the same as if the property does not exist. - `String` | A character string, i.e. text. - `Boolean` | A boolean value, either `true` or `false`. - `Integer` | An integer number. - `Float` | A floating-point number, i.e. a real number. - `List` | A list containing any number of property values of any supported type. It can be used to store multiple values under a single property name. - `Map` | A mapping of string keys to values of any supported type. - - Note that even though it's possible to store `List` and `Map` property values, it is not possible to modify them. It is however possible to replace them completely. So, the following queries are legal: - -```opencypher -CREATE (:Node {property: [1, 2, 3]}) -CREATE (:Node {property: {key: "value"}}) -``` - -However, these queries are not: - -```opencypher -MATCH (n:Node) SET n.property[0] = 0 -MATCH (n:Node) SET n.property.key = "other value" -``` - -### Cold data on disk - -Although *Memgraph* is an in-memory database by default, it offers an option -to store a certain amount of data on disk. More precisely, the user can pass -a list of properties they wish to keep stored on disk via the command line. -In certain cases, this might result in a significant performance boost due to -reduced memory usage. It is recommended to use this feature on large, -cold properties, i.e. properties that are rarely accessed. - -For example, a user of a library database might identify author biographies -and book summaries as cold properties. In that case, the user should run -*Memgraph* as follows: - -```bash -/usr/lib/memgraph/memgraph --properties-on-disk biography,summary -``` - -Note that the usage of *Memgraph* has not changed, i.e. durability and -data recovery mechanisms are still in place and the query language remains -the same. It is also important to note that the user cannot change the storage -location of a property while *Memgraph* is running. Naturally, the user can -reload their database from snapshot, provide a different list of properties on -disk and rest assured that only those properties will be stored on disk. diff --git a/docs/user_technical/concepts/03_graph-algorithms.md b/docs/user_technical/concepts/03_graph-algorithms.md deleted file mode 100644 index e822123fd..000000000 --- a/docs/user_technical/concepts/03_graph-algorithms.md +++ /dev/null @@ -1,156 +0,0 @@ -## Graph Algorithms - -### Introduction - -The graph is a mathematical structure used to describe a set of objects in which -some pairs of objects are "related" in some sense. Generally, we consider -those objects as abstractions named `nodes` (also called `vertices`). -Aforementioned relations between nodes are modelled by an abstraction named -`edge` (also called `relationship`). - -It turns out that a lot of real-world problems can be successfully modeled -using graphs. Some natural examples would contain railway networks between -cities, computer networks, piping systems and Memgraph itself. - -This article outlines some of the most important graph algorithms -that are internally used by Memgraph. We believe that advanced users could -significantly benefit from obtaining basic knowledge about those algorithms. -The users should also note that this article does not contain an in-depth -analysis of algorithms and their implementation details since those are -well documented in the appropriate literature and, in our opinion, go well out -of scope for user documentation. That being said, we will include the relevant -information for using Memgraph effectively and efficiently. - -Contents of this article include: - - * [Breadth First Search (BFS)](#breadth-first-search) - * [Weighted Shortest Path (WSP)](#weighted-shortest-path) - - -### Breadth First Search - -[Breadth First Search](https://en.wikipedia.org/wiki/Breadth-first_search) -is a way of traversing a graph data structure. The -traversal starts from a single node (usually referred to as source node) and, -during the traversal, breadth is prioritized over depth, hence the name of the -algorithm. More precisely, when we visit some node, we can safely assume that -we have already visited all nodes that are fewer edges away from a source node. -An interesting side-effect of traversing a graph in BFS order is the fact -that, when we visit a particular node, we can easily find a path from -the source node to the newly visited node with the least number of edges. -Since in this context we disregard the edge weights, we can say that BFS is -a solution to an unweighted shortest path problem. - -The algorithm itself proceeds as follows: - - * Keep around a set of nodes that are equidistant from the source node. - Initially, this set contains only the source node. - * Expand to all not yet visited nodes that are a single edge away from that - set. Note that the set of those nodes is also equidistant from the source - node. - * Replace the set with a set of nodes obtained in the previous step. - * Terminate the algorithm when the set is empty. - -The order of visited nodes is nicely visualized in the following animation from -Wikipedia. Note that each row contains nodes that are equidistant from the -source and thus represents one of the sets mentioned above. - -![visualization](https://upload.wikimedia.org/wikipedia/commons/5/5d/Breadth-First-Search-Algorithm.gif) - -The standard BFS implementation skews from the above description by relying on -a FIFO (first in, first out) queue data structure. Nevertheless, the -functionality is equivalent and its runtime is bounded by `O(|V| + |E|)` where -`V` denotes the set of nodes and `E` denotes the set of edges. Therefore, -it provides a more efficient way of finding unweighted shortest paths than -running [Dijkstra's algorithm](#weighted-shortest-path) on a graph -with edge weights equal to `1`. - -### Weighted Shortest Path - -In [graph theory](https://en.wikipedia.org/wiki/Graph_theory), weighted shortest -path problem is the problem of finding a path between two nodes in a graph such -that the sum of the weights of edges connecting nodes on the path is minimized. - -#### Dijkstra's algorithm - -One of the most important algorithms for finding weighted shortest paths is -[Dijkstra's algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm). -Our implementation uses a modified version of this algorithm that can handle -length restriction. The length restriction parameter is optional and when it's -not set it could increase the complexity of the algorithm. It is important to -note that the term "length" in this context denotes the number of traversed -edges and not the sum of their weights. - -The algorithm itself is based on a couple of greedy observations and could -be expressed in natural language as follows: - - * Keep around a set of already visited nodes along with their corresponding - shortest paths from source node. Initially, this set contains only the - source node with the shortest distance of `0`. - * Find an edge that goes from a visited node to an unvisited one such that the - shortest path from source to the visited node increased by the weight of - that edge is minimized. Traverse that edge and add a newly visited node with - appropriate distance to the set of already visited nodes. - * Repeat the process until the destination node is visited. - -The described algorithm is nicely visualized in the following animation from -Wikipedia. Note that edge weights correspond to the Euclidean distance between -nodes which represent points on a plane. - -![visualization](https://upload.wikimedia.org/wikipedia/commons/e/e4/DijkstraDemo.gif) - -Using appropriate data structures the worst-case performance of our -implementation can be expressed as `O(|E| + |V|log|V|)` where `E` denotes -a set of edges and `V` denotes the set of nodes. - -A sample query that finds a shortest path between two nodes looks as follows: - -```opencypher -MATCH (a {id: 723})-[edge_list *wShortest 10 (e, n | e.weight) total_weight]-(b {id: 882}) RETURN * -``` - -This query has an upper bound length restriction set to `10`. This means that no -path that traverses more than `10` edges will be considered as a valid result. - -##### Upper Bound Implications - -Since the upper bound parameter is optional, we can have different results based -on this parameter. - -Consider the following graph and sample queries. - -![sample-graph](../data/graph.png) - -```opencypher -MATCH (a {id: 0})-[edge_list *wShortest 3 (e, n | e.weight) total_weight]-(b {id: 5}) RETURN * -``` - -```opencypher -MATCH (a {id: 0})-[edge_list *wShortest (e, n | e.weight) total_weight]-(b {id: 5}) RETURN * -``` - -The first query will try to find the weighted shortest path between nodes `0` -and `5` with the restriction on the path length set to `3`, and the second query -will try to find the weighted shortest path with no restriction on the path -length. - -The expected result for the first query is `0 -> 1 -> 4 -> 5` with the total -cost of `12`, while the expected result for the second query is -`0 -> 2 -> 3 -> 4 -> 5` with the total cost of `11`. Obviously, the second -query can find the true shortest path because it has no restrictions on the -length. - -To handle cases when the length restriction is set, *weighted shortest path* -algorithm uses both node and distance as the state. This causes the search -space to increase by the factor of the given upper bound. On the other hand, not -setting the upper bound parameter, the search space might contain the whole -graph. - -Because of this, one should always try to narrow down the upper bound limit to -be as precise as possible in order to have a more performant query. - -### Where to next? - -For some real-world application of WSP we encourage you to visit our article -on [exploring the European road network](../tutorials/04_exploring-the-european-road-network.md) -which was specially crafted to showcase our graph algorithms. diff --git a/docs/user_technical/concepts/04_indexing.md b/docs/user_technical/concepts/04_indexing.md deleted file mode 100644 index 5c33d4010..000000000 --- a/docs/user_technical/concepts/04_indexing.md +++ /dev/null @@ -1,92 +0,0 @@ -## Indexing - -### Introduction - -A database index is a data structure used to improve the speed of data retrieval -within a database at the cost of additional writes and storage space for -maintaining the index data structure. - -Armed with deep understanding of their data model and use-case, users can decide -which data to index and, by doing so, significantly improve their data retrieval -efficiency - -### Index Types - -At Memgraph, we support two types of indexes: - - * label index - * label-property index - -Label indexing is enabled by default in Memgraph, i.e., Memgraph automatically -indexes labeled data. By doing so we optimize queries which fetch nodes by -label: - -```opencypher -MATCH (n: Label) ... RETURN n -``` - -Indexes can also be created on data with a specific combination of label and -property, hence the name label-property index. This operation needs to be -specified by the user and should be used with a specific data model and -use-case in mind. - -For example, suppose we are storing information about certain people in our -database and we are often interested in retrieving their age. In that case, -it might be beneficial to create an index on nodes labeled as `:Person` which -have a property named `age`. We can do so by using the following language -construct: - -```opencypher -CREATE INDEX ON :Person(age) -``` - -After the creation of that index, those queries will be more efficient due to -the fact that Memgraph's query engine will not have to fetch each `:Person` node -and check whether the property exists. Moreover, even if all nodes labeled as -`:Person` had an `age` property, creating such index might still prove to be -beneficial. The main reason is that entries within that index are kept sorted -by property value. Queries such as the following are therefore more efficient: - -```opencypher -MATCH (n :Person {age: 42}) RETURN n -``` - -Index based retrieval can also be invoked on queries with `WHERE` statements. -For instance, the following query will have the same effect as the previous -one: - -```opencypher -MATCH (n) WHERE n:Person AND n.age = 42 RETURN n -``` - -Naturally, indexes will also be used when filtering based on less than or -greater than comparisons. For example, filtering all minors (persons -under 18 years of age under Croatian law) using the following query will use -index based retrieval: - -```opencypher -MATCH (n) WHERE n:PERSON and n.age < 18 RETURN n -``` - -Bear in mind that `WHERE` filters could contain arbitrarily complex expressions -and index based retrieval might not be used. Nevertheless, we are continually -improving our index usage recognition algorithms. - -### Underlying Implementation - -The central part of our index data structure is a highly-concurrent skip list. -Skip lists are probabilistic data structures that allow fast search within an -ordered sequence of elements. The structure itself is built in layers where the -bottom layer is an ordinary linked list that preserves the order. Each higher -level can be imagined as a highway for layers below. - -The implementation details behind skip list operations are well documented -in the literature and are out of scope for this article. Nevertheless, we -believe that it is important for more advanced users to understand the following -implications of this data structure (`n` denotes the current number of elements -in a skip list): - - * Average insertion time is `O(log(n))` - * Average deletion time is `O(log(n))` - * Average search time is `O(log(n))` - * Average memory consumption is `O(n)` diff --git a/docs/user_technical/data/graph.png b/docs/user_technical/data/graph.png deleted file mode 100644 index 31e011b3d..000000000 Binary files a/docs/user_technical/data/graph.png and /dev/null differ diff --git a/docs/user_technical/how_to_guides/01_how-to-guides-overview.md b/docs/user_technical/how_to_guides/01_how-to-guides-overview.md deleted file mode 100644 index 661da8611..000000000 --- a/docs/user_technical/how_to_guides/01_how-to-guides-overview.md +++ /dev/null @@ -1,12 +0,0 @@ -## How-to Guides Overview - -Articles within the how-to guides section serve as a cookbook for getting -things done as fast as possible. These articles tend to provide a step-by-step -guide on how to use certain Memgraph feature or solve a particular problem. - -So far we have covered the following topics: - - * [How to Import Data?](02_import-tools.md) - * [How to Query Memgraph Programmatically?](03_query-memgraph-programmatically.md) - * [How to Ingest Data Using Kafka](04_ingest-data-using-kafka.md) - * [How to Manage User Privileges](05_manage-user-privileges.md) diff --git a/docs/user_technical/how_to_guides/02_import-data.md b/docs/user_technical/how_to_guides/02_import-data.md deleted file mode 100644 index 643fb8e57..000000000 --- a/docs/user_technical/how_to_guides/02_import-data.md +++ /dev/null @@ -1,118 +0,0 @@ -## How to Import Data? - -Memgraph comes with tools for importing data into the database. Currently, -only import of CSV formatted is supported. We plan to support more formats in -the future. - -### CSV Import Tool - -CSV data should be in Neo4j CSV compatible format. Detailed format -specification can be found -[here](https://neo4j.com/docs/operations-manual/current/tools/import/file-header-format/). - -The import tool is run from the console, using the `mg_import_csv` command. - -If you installed Memgraph using Docker, you will need to run the importer -using the following command: - -```bash -docker run -v mg_lib:/var/lib/memgraph -v mg_etc:/etc/memgraph -v mg_import:/import-data \ - --entrypoint=mg_import_csv memgraph -``` - -You can pass CSV files containing node data using the `--nodes` option. -Multiple files can be specified by repeating the `--nodes` option. At least -one node file should be specified. Similarly, graph edges (also known as -relationships) are passed via the `--relationships` option. Multiple -relationship files are imported by repeating the option. Unlike nodes, -relationships are not required. - -After reading the CSV files, the tool will by default search for the installed -Memgraph configuration. If the configuration is found, the data will be -written in the configured durability directory. If the configuration isn't -found, you will need to use the `--out` option to specify the output file. You -can use the same option to override the default behaviour. - -Memgraph will recover the imported data on the next startup by looking in the -durability directory. - -For information on other options, run: - -```bash -mg_import_csv --help -``` - -When using Docker, this translates to: - -```bash -docker run --entrypoint=mg_import_csv memgraph --help -``` - -#### Example - -Let's import a simple dataset. - -Store the following in `comment_nodes.csv`. - -```csv -id:ID(COMMENT_ID),country:string,browser:string,content:string,:LABEL -0,Croatia,Chrome,yes,Message;Comment -1,United Kingdom,Chrome,thanks,Message;Comment -2,Germany,,LOL,Message;Comment -3,France,Firefox,I see,Message;Comment -4,Italy,Internet Explorer,fine,Message;Comment -``` - -Now, let's add `forum_nodes.csv`. - -```csv -id:ID(FORUM_ID),title:string,:LABEL -0,General,Forum -1,Support,Forum -2,Music,Forum -3,Film,Forum -4,Programming,Forum -``` - -And finally, set relationships between comments and forums in -`relationships.csv`. - -```csv -:START_ID(COMMENT_ID),:END_ID(FORUM_ID),:TYPE -0,0,POSTED_ON -1,1,POSTED_ON -2,2,POSTED_ON -3,3,POSTED_ON -4,4,POSTED_ON -``` - -Now, you can import the dataset in Memgraph. - -WARNING: Your existing recovery data will be considered obsolete, and Memgraph -will load the new dataset. - -Use the following command: - -```bash -mg_import_csv --overwrite --nodes=comment_nodes.csv --nodes=forum_nodes.csv --relationships=relationships.csv -``` - -If using Docker, things are a bit more complicated. First you need to move the -CSV files where the Docker image can see them: - -```bash -mkdir -p /var/lib/docker/volumes/mg_import/_data -cp comment_nodes.csv forum_nodes.csv relationships.csv /var/lib/docker/volumes/mg_import/_data -``` - -Then, run the importer with the following: - -```bash -docker run -v mg_lib:/var/lib/memgraph -v mg_etc:/etc/memgraph -v mg_import:/import-data \ - --entrypoint=mg_import_csv memgraph \ - --overwrite \ - --nodes=/import-data/comment_nodes.csv --nodes=/import-data/forum_nodes.csv \ - --relationships=/import-data/relationships.csv -``` - -Next time you run Memgraph, the dataset will be loaded. diff --git a/docs/user_technical/how_to_guides/03_query-memgraph-programmatically.md b/docs/user_technical/how_to_guides/03_query-memgraph-programmatically.md deleted file mode 100644 index 33fe7953a..000000000 --- a/docs/user_technical/how_to_guides/03_query-memgraph-programmatically.md +++ /dev/null @@ -1,213 +0,0 @@ -## How to Query Memgraph Programmatically? - -### 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 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!"); - } -} -``` diff --git a/docs/user_technical/how_to_guides/04_ingest-data-using-kafka.md b/docs/user_technical/how_to_guides/04_ingest-data-using-kafka.md deleted file mode 100644 index f9a8782ef..000000000 --- a/docs/user_technical/how_to_guides/04_ingest-data-using-kafka.md +++ /dev/null @@ -1,116 +0,0 @@ -## How to Ingest Data Using Kafka - -Apache Kafka is an open-source stream-processing software platform. The project -aims to provide a unified, high-throughput, low-latency platform for handling -real-time data feeds. - -Memgraph offers easy data import at the source using Kafka as the -high-throughput messaging system. - -At this point, we strongly advise you to read the streaming section of our -[reference guide](../reference_guide/07_graph-streams.md) - -In this article, we assume you have a local instance of Kafka. You can find -more about running Kafka [here](https://kafka.apache.org/quickstart). - -From this point forth, we assume you have a instance of Kafka running on -`localhost:9092` with a topic `test` and that you've started Memgraph and have -Memgraph client running. - -Each Kafka stream in Memgraph requires a transform script written in `Python` -that knows how to interpret incoming data and transform the data to queries that -Memgraph understands. Lets assume you have script available on -`http://localhost/transform.py`. - -Lets also assume the Kafka topic contains two types of messages: - - * Node creation: the message contains a single number, the node id. - * Edge creation: the message contains two numbers, origin node id and - destination node id. - -In order to create a stream input the following query in the client: - -```opencypher -CREATE STREAM mystream AS LOAD DATA KAFKA 'localhost:9092' WITH TOPIC 'test' WITH -TRANSFORM 'http://localhost/transform.py' -``` - -This will create the stream inside Memgraph but will not start it yet. However, -if the Kafka instance isn't available on the given URI, or the topic doesn't -exist, the query will fail with an appropriate message. - -E.g. if the transform script can't be found at the given URI, the following -error will be shown: - -```plaintext -Client received exception: Couldn't get the transform script from http://localhost/transform.py -``` -Similarly, if the given Kafka topic doesn't exist, we'll get the following: - -```plaintext -Client received exception: Kafka stream mystream, topic not found -``` - -After a successful stream creation, you can check the status of all streams by -executing: - -```opencypher -SHOW STREAMS -``` - -This should produce the following output: - -```plaintext -+----------+----------------+-------+------------------------------+---------+ -| name | uri | topic | transform | status | -+---------------------------+--------------------------------------+---------+ -| mystream | localhost:9092 | test | http://localhost/memgraph.py | stopped | -+----------+----------------+-------+------------------------------+---------+ -``` -As you can notice, the status of this stream is stopped. - -In order to see if everything is correct, you can test the stream by executing: - -```opencypher -TEST STREAM mystream; -``` - -This will ingest data from Kafka, but instead of writing it to Memgraph, it will -just output the result. - -If the `test` Kafka topic would contain two messages, `1` and `1 2` the result -of the `TEST STREAM` query would look like: - -```plaintext -+-------------------------------------------------------------------------------+-------------------------+ -| query | params | -+-------------------------------------------------------------------------------+-------------------------+ -| CREATE (:Node {id: $id}) | {id:"1"} | -| MATCH (n:Node {id: $from_id}), (m:Node {id: $to_id}) CREATE (n)-[:Edge]->(m) | {from_id:"1",to_id:"2"} | -+-------------------------------------------------------------------------------+-------------------------+ -``` - -To start ingesting data from a stream, you need to execute the following query: - -```opencypher -START STREAM mystream; -``` - -If we check the stream status now, the output would look like this: - -```plaintext -+----------+----------------+-------+------------------------------+---------+ -| name | uri | topic | transform | status | -+---------------------------+--------------------------------------+---------+ -| mystream | localhost:9092 | test | http://localhost/memgraph.py | running | -+----------+----------------+-------+------------------------------+---------+ -``` - -To stop ingesting data, the stop stream query needs to be executed: - -```opencypher -STOP STREAM mystream; -``` - -If Memgraph shuts down, all streams that existed before the shutdown are going -to be recovered. diff --git a/docs/user_technical/how_to_guides/05_manage-user-privileges.md b/docs/user_technical/how_to_guides/05_manage-user-privileges.md deleted file mode 100644 index 5baf510aa..000000000 --- a/docs/user_technical/how_to_guides/05_manage-user-privileges.md +++ /dev/null @@ -1,142 +0,0 @@ -## How to Manage User Privileges? - -Most databases have multiple users accessing and modifying -data within the database. This might pose a serious security concern for the -system administrators that wish to grant only certain privileges to certain -users. A typical example would be an internal database of some company which -tracks data about their employees. Naturally, only certain users of the database -should be able to perform queries which modify that data. - -At Memgraph, we provide the administrators with the option of granting, -denying or revoking a certain set of privileges to some users or groups of users -(i.e. users that are assigned a specific user role), thereby eliminating such -security concerns. - -By default, anyone can connect to Memgraph and is granted all privileges. -After the first user is created, Memgraph will execute a query if and only -if either a user or its role is granted that privilege and neither the -user nor its role are denied that privilege. Otherwise, Memgraph will not -execute that specific query. Note that `DENY` is a stronger -operation than `GRANT`. This is also notable from the fact that if neither the -user nor its role are explicitly granted or denied a certain privilege, that -user will not be able to perform that specific query. This effect also is known -as a silent deny. The information above is neatly condensed in the following -table: - -User Status | Role Status | Effective Status ---------------------------------------------- -GRANT | GRANT | GRANT -GRANT | DENY | DENY -GRANT | NULL | GRANT -DENY | GRANT | DENY -DENY | DENY | DENY -DENY | NULL | DENY -NULL | GRANT | GRANT -NULL | DENY | DENY -NULL | NULL | DENY - -All supported commands that deal with accessing or modifying users, user -roles and privileges can only be executed by users that are granted the -`AUTH` privilege. All of those commands are listed in the appropriate -[reference guide](../reference_guide/security.md). - -At the moment, privileges are confined to users' abilities to perform certain -`OpenCypher` queries. Namely users can be given permission to execute a subset -of the following commands: `CREATE`, `DELETE`, `MATCH`, `MERGE`, `SET`, -`REMOVE`, `INDEX`, `AUTH`, `STREAM`. - -We could naturally cluster those privileges into groups: - - * Privilege to access data (`MATCH`) - * Privilege to modify data (`MERGE`, `SET`) - * Privilege to create and delete data (`CREATE`, `DELETE`, `REMOVE`) - * Privilege to index data (`INDEX`) - * Privilege to use data streaming (`STREAM`) - * Privilege to view and alter users, roles and privileges (`AUTH`) - -If you are unfamiliar with any of these commands, you can look them up in our -[reference guide](../reference_guide/01_reference-overview.md). - -Similarly, the complete list of commands which can be executed under `AUTH` -privilege can be viewed in the -[appropriate article](../reference_guide/08_security.md) within our reference -guide. - -The remainder of this article outlines a recommended workflow of -user management within an internal database of a fictitious company. - -### Creating an Administrator - -As it was stated in the introduction, after the first user is created, Memgraph -will execute a query for a given user if the effective status of a corresponding -privilege evaluates to `GRANT`. As a corollary, the person that created the -first user might not be able to perform any meaningful action after their -session had ended. To prevent that from happening, we strongly recommend -the first created user to be an administrator which is granted all privileges. - -Therefore, let's create a user named `admin` and set its' password to `0000`. -This can be done by executing: - -```openCypher - CREATE USER admin IDENTIFIED BY '0000'; -``` - -Granting all privileges to our `admin` user can be done as follows: - -```openCypher - GRANT ALL PRIVILEGES to admin; -``` - -At this point, the current user can close their session and log into a new -one as an `admin` user they have just created. The remainder of the article -is written from the viewpoint of an administrator which is granted -all privileges. - -### Creating Other Users - -Our fictitious company is internally divided into teams, and each team has -its own supervisor. All employees of the company need to access and modify -data within the database. - -Creating a user account for a new hire named Alice can be done as follows: - -```openCypher - CREATE USER alice IDENTIFIED BY '0042'; -``` - -Alice should also be granted a privilege to access data, which can be done by -executing the following: - -```openCypher - GRANT MATCH, MERGE, SET TO alice; -``` - -### Creating User Roles - -Each team supervisor needs to have additional privileges that allow them to -create new data or delete existing data from the database. Instead of tediously -granting additional privileges to each supervisor using language constructs from -the previous chapter, we could do so by creating a new user role for -supervisors. - -Creating a user role named `supervisor` can be done by executing the following -command: - -```openCypher - CREATE ROLE supervisor; -``` - -Granting the privilege to create and delete data to our newly created role can -be done as follows: - -```openCypher - GRANT CREATE, DELETE, REMOVE TO supervisor; -``` - -Finally, we need to assign that role to each of the supervisors. Suppose, a user -named `bob` is indeed a supervisor within the company. Assigning them that role -within the database can be done by the following command: - -``` - SET ROLE FOR bob TO supervisor; -``` diff --git a/docs/user_technical/quick-start.md b/docs/user_technical/quick-start.md deleted file mode 100644 index 32add76d7..000000000 --- a/docs/user_technical/quick-start.md +++ /dev/null @@ -1,290 +0,0 @@ -## 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_.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-.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--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 -``` -#### 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](how_to_guides/03_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 -[reference guide](reference_guide/01_reference-overview.md) article. -For real-world examples of how to use Memgraph, we strongly suggest reading -through the following articles: - - * [Analyzing TED Talks](tutorials/02_analyzing-TED-talks.md) - * [Graphing the Premier League](tutorials/03_graphing-the-premier-league.md) - * [Exploring the European Road Network](tutorials/04_exploring-the-european-road-network.md) - -Details on what can be stored in Memgraph can be found in the article about -[Data Storage](concepts/02_storage.md). - -We *welcome and encourage* your feedback! diff --git a/docs/user_technical/reference_guide/01_reference-overview.md b/docs/user_technical/reference_guide/01_reference-overview.md deleted file mode 100644 index 06f189319..000000000 --- a/docs/user_technical/reference_guide/01_reference-overview.md +++ /dev/null @@ -1,22 +0,0 @@ -## Reference Overview - -[*openCypher*](http://www.opencypher.org/) is a query language for querying -graph databases. It aims to be intuitive and easy to learn, while -providing a powerful interface for working with graph based data. - -*Memgraph* supports most of the commonly used constructs of the language. The -reference guide contains the details of implemented features. Additionally, -not yet supported features of the language are listed. - -Our reference guide currently consists of the following articles: - - * [Reading Existing Data](02_reading-existing-data.md) - * [Writing New Data](03_writing-new-data.md) - * [Reading and Writing](04_reading-and-writing.md) - * [Indexing](05_indexing.md) - * [Graph Algorithms](06_graph-algorithms.md) - * [Graph Streams](07_graph-streams.md) - * [Security](08_security.md) - * [Dynamic Graph Partitioner](09_dynamic-graph-partitioner.md) - * [Other Features](10_other-features.md) - * [Differences](11_differences.md) diff --git a/docs/user_technical/reference_guide/02_reading-existing-data.md b/docs/user_technical/reference_guide/02_reading-existing-data.md deleted file mode 100644 index 7509a6562..000000000 --- a/docs/user_technical/reference_guide/02_reading-existing-data.md +++ /dev/null @@ -1,280 +0,0 @@ -## Reading Existing Data - -The simplest usage of the language is to find data stored in the -database. For that purpose, the following clauses are offered: - - * `MATCH`, which searches for patterns; - * `WHERE`, for filtering the matched data and - * `RETURN`, for defining what will be presented to the user in the result - set. - * `UNION` and `UNION ALL` for combining results from multiple queries. - -### MATCH - -This clause is used to obtain data from Memgraph by matching it to a given -pattern. For example, to find each node in the database, you can use the -following query. - -```opencypher -MATCH (node) RETURN node -``` - -Finding connected nodes can be achieved by using the query: - -```opencypher -MATCH (node1)-[connection]-(node2) RETURN node1, connection, node2 -``` - -In addition to general pattern matching, you can narrow the search down by -specifying node labels and properties. Similarly, edge types and properties -can also be specified. For example, finding each node labeled as `Person` and -with property `age` being 42, is done with the following query. - -```opencypher -MATCH (n :Person {age: 42}) RETURN n -``` - -While their friends can be found with the following. - -```opencypher -MATCH (n :Person {age: 42})-[:FriendOf]-(friend) RETURN friend -``` - -There are cases when a user needs to find data which is connected by -traversing a path of connections, but the user doesn't know how many -connections need to be traversed. openCypher allows for designating patterns -with *variable path lengths*. Matching such a path is achieved by using the -`*` (*asterisk*) symbol inside the edge element of a pattern. For example, -traversing from `node1` to `node2` by following any number of connections in a -single direction can be achieved with: - -```opencypher -MATCH (node1)-[r*]->(node2) RETURN node1, r, node2 -``` - -If paths are very long, finding them could take a long time. To prevent that, -a user can provide the minimum and maximum length of the path. For example, -paths of length between 2 and 4 can be obtained with a query like: - -```opencypher -MATCH (node1)-[r*2..4]->(node2) RETURN node1, r, node2 -``` - -It is possible to name patterns in the query and return the resulting paths. -This is especially useful when matching variable length paths: - -```opencypher -MATCH path = ()-[r*2..4]->() RETURN path -``` - -More details on how `MATCH` works can be found -[here](https://neo4j.com/docs/developer-manual/current/cypher/clauses/match/). - -The `MATCH` clause can be modified by prepending the `OPTIONAL` keyword. -`OPTIONAL MATCH` clause behaves the same as a regular `MATCH`, but when it -fails to find the pattern, missing parts of the pattern will be filled with -`null` values. Examples can be found -[here](https://neo4j.com/docs/developer-manual/current/cypher/clauses/optional-match/). - -### WHERE - -You have already seen that simple filtering can be achieved by using labels -and properties in `MATCH` patterns. When more complex filtering is desired, -you can use `WHERE` paired with `MATCH` or `OPTIONAL MATCH`. For example, -finding each person older than 20 is done with the this query. - -```opencypher -MATCH (n :Person) WHERE n.age > 20 RETURN n -``` - -Additional examples can be found -[here](https://neo4j.com/docs/developer-manual/current/cypher/clauses/where/). - -### RETURN - -The `RETURN` clause defines which data should be included in the resulting -set. Basic usage was already shown in the examples for `MATCH` and `WHERE` -clauses. Another feature of `RETURN` is renaming the results using the `AS` -keyword. - -Example. - -```opencypher -MATCH (n :Person) RETURN n AS people -``` - -That query would display all nodes under the header named `people` instead of -`n`. - -When you want to get everything that was matched, you can use the `*` -(*asterisk*) symbol. - -This query: - -```opencypher -MATCH (node1)-[connection]-(node2) RETURN * -``` - -is equivalent to: - -```opencypher -MATCH (node1)-[connection]-(node2) RETURN node1, connection, node2 -``` - -`RETURN` can be followed by the `DISTINCT` operator, which will remove -duplicate results. For example, getting unique names of people can be achieved -with: - -```opencypher -MATCH (n :Person) RETURN DISTINCT n.name -``` - -Besides choosing what will be the result and how it will be named, the -`RETURN` clause can also be used to: - - * limit results with `LIMIT` sub-clause; - * skip results with `SKIP` sub-clause; - * order results with `ORDER BY` sub-clause and - * perform aggregations (such as `count`). - -More details on `RETURN` can be found -[here](https://neo4j.com/docs/developer-manual/current/cypher/clauses/return/). - -#### SKIP & LIMIT - -These sub-clauses take a number of how many results to skip or limit. -For example, to get the first 3 results you can use this query. - -```opencypher -MATCH (n :Person) RETURN n LIMIT 3 -``` - -If you want to get all the results after the first 3, you can use the -following. - -```opencypher -MATCH (n :Person) RETURN n SKIP 3 -``` - -The `SKIP` and `LIMIT` can be combined. So for example, to get the 2nd result, -you can do: - -```opencypher -MATCH (n :Person) RETURN n SKIP 1 LIMIT 1 -``` - -#### ORDER BY - -Since the patterns which are matched can come in any order, it is very useful -to be able to enforce some ordering among the results. In such cases, you can -use the `ORDER BY` sub-clause. - -For example, the following query will get all `:Person` nodes and order them -by their names. - -```opencypher -MATCH (n :Person) RETURN n ORDER BY n.name -``` - -By default, ordering will be in the ascending order. To change the order to be -descending, you should append `DESC`. - -For example, to order people by their name descending, you can use this query. - -```opencypher -MATCH (n :Person) RETURN n ORDER BY n.name DESC -``` - -You can also order by multiple variables. The results will be sorted by the -first variable listed. If the values are equal, the results are sorted by the -second variable, and so on. - -Example. Ordering by first name descending and last name ascending. - -```opencypher -MATCH (n :Person) RETURN n ORDER BY n.name DESC, n.lastName -``` - -Note that `ORDER BY` sees only the variable names as carried over by `RETURN`. -This means that the following will result in an error. - -```opencypher -MATCH (n :Person) RETURN old AS new ORDER BY old.name -``` - -Instead, the `new` variable must be used: - -```opencypher -MATCH (n: Person) RETURN old AS new ORDER BY new.name -``` - -The `ORDER BY` sub-clause may come in handy with `SKIP` and/or `LIMIT` -sub-clauses. For example, to get the oldest person you can use the following. - -```opencypher -MATCH (n :Person) RETURN n ORDER BY n.age DESC LIMIT 1 -``` - -##### Aggregating - -openCypher has functions for aggregating data. Memgraph currently supports -the following aggregating functions. - - * `avg`, for calculating the average. - * `collect`, for collecting multiple values into a single list or map. If - given a single expression values are collected into a list. If given two - expressions, values are collected into a map where the first expression - denotes map keys (must be string values) and the second expression denotes - map values. - * `count`, for counting the resulting values. - * `max`, for calculating the maximum result. - * `min`, for calculating the minimum result. - * `sum`, for getting the sum of numeric results. - -Example, calculating the average age: - -```opencypher -MATCH (n :Person) RETURN avg(n.age) AS averageAge -``` - -Collecting items into a list: - -```opencypher -MATCH (n :Person) RETURN collect(n.name) AS list_of_names -``` - -Collecting items into a map: - -```opencypher -MATCH (n :Person) RETURN collect(n.name, n.age) AS map_name_to_age -``` - -Click -[here](https://neo4j.com/docs/developer-manual/current/cypher/functions/aggregating/) -for additional details on how aggregations work. - -### UNION and UNION ALL - -openCypher supports combining results from multiple queries into a single result -set. That result will contain rows that belong to queries in the union -respecting the union type. - -Using `UNION` will contain only distinct rows while `UNION ALL` will keep all -rows from all given queries. - -Restrictions when using `UNION` or `UNION ALL`: - * The number and the names of columns returned by queries must be the same - for all of them. - * There can be only one union type between single queries, i.e. a query can't - contain both `UNION` and `UNION ALL`. - -Example, get distinct names that are shared between persons and movies: - -```opencypher -MATCH(n: Person) RETURN n.name AS name UNION MATCH(n: Movie) RETURN n.name AS name -``` - -Example, get all names that are shared between persons and movies (including duplicates): - -```opencypher -MATCH(n: Person) RETURN n.name AS name UNION ALL MATCH(n: Movie) RETURN n.name AS name diff --git a/docs/user_technical/reference_guide/03_writing-new-data.md b/docs/user_technical/reference_guide/03_writing-new-data.md deleted file mode 100644 index 8eb6b910c..000000000 --- a/docs/user_technical/reference_guide/03_writing-new-data.md +++ /dev/null @@ -1,92 +0,0 @@ -## Writing New Data - -For adding new data, you can use the following clauses. - - * `CREATE`, for creating new nodes and edges. - * `SET`, for adding new or updating existing labels and properties. - * `DELETE`, for deleting nodes and edges. - * `REMOVE`, for removing labels and properties. - -You can still use the `RETURN` clause to produce results after writing, but it -is not mandatory. - -Details on which kind of data can be stored in *Memgraph* can be found in -[Data Storage](../concepts/02_storage.md) chapter. - -### CREATE - -This clause is used to add new nodes and edges to the database. The creation -is done by providing a pattern, similarly to `MATCH` clause. - -For example, to create 2 new nodes connected with a new edge, use this query. - -```opencypher -CREATE (node1)-[:edge_type]->(node2) -``` - -Labels and properties can be set during creation using the same syntax as in -`MATCH` patterns. For example, creating a node with a label and a -property: - -```opencypher -CREATE (node :Label {property: "my property value"}) -``` - -Additional information on `CREATE` is -[here](https://neo4j.com/docs/developer-manual/current/cypher/clauses/create/). - -### SET - -The `SET` clause is used to update labels and properties of already existing -data. - -Example. Incrementing everyone's age by 1. - -```opencypher -MATCH (n :Person) SET n.age = n.age + 1 -``` - -Click -[here](https://neo4j.com/docs/developer-manual/current/cypher/clauses/create/) -for a more detailed explanation on what can be done with `SET`. - -### DELETE - -This clause is used to delete nodes and edges from the database. - -Example. Removing all edges of a single type. - -```opencypher -MATCH ()-[edge :type]-() DELETE edge -``` - -When testing the database, you want to often have a clean start by deleting -every node and edge in the database. It is reasonable that deleting each node -should delete all edges coming into or out of that node. - -```opencypher -MATCH (node) DELETE node -``` - -But, openCypher prevents accidental deletion of edges. Therefore, the above -query will report an error. Instead, you need to use the `DETACH` keyword, -which will remove edges from a node you are deleting. The following should -work and *delete everything* in the database. - -```opencypher -MATCH (node) DETACH DELETE node -``` - -More examples are -[here](https://neo4j.com/docs/developer-manual/current/cypher/clauses/delete/). - -### REMOVE - -The `REMOVE` clause is used to remove labels and properties from nodes and -edges. - -Example. - -```opencypher -MATCH (n :WrongLabel) REMOVE n :WrongLabel, n.property -``` diff --git a/docs/user_technical/reference_guide/04_reading-and-writing.md b/docs/user_technical/reference_guide/04_reading-and-writing.md deleted file mode 100644 index 409501fd9..000000000 --- a/docs/user_technical/reference_guide/04_reading-and-writing.md +++ /dev/null @@ -1,51 +0,0 @@ -## Reading and Writing - -OpenCypher supports combining multiple reads and writes using the -`WITH` clause. In addition to combining, the `MERGE` clause is provided which -may create patterns if they do not exist. - -### WITH - -The write part of the query cannot be simply followed by another read part. In -order to combine them, `WITH` clause must be used. The names this clause -establishes are transferred from one part to another. - -For example, creating a node and finding all nodes with the same property. - -```opencypher -CREATE (node {property: 42}) WITH node.property AS propValue -MATCH (n {property: propValue}) RETURN n -``` - -Note that the `node` is not visible after `WITH`, since only `node.property` -was carried over. - -This clause behaves very much like `RETURN`, so you should refer to features -of `RETURN`. - -### MERGE - -The `MERGE` clause is used to ensure that a pattern you are looking for exists -in the database. This means that if the pattern is not found, it will be -created. In a way, this clause is like a combination of `MATCH` and `CREATE`. - - -Example. Ensure that a person has at least one friend. - -```opencypher -MATCH (n :Person) MERGE (n)-[:FriendOf]->(m) -``` - -The clause also provides additional features for updating the values depending -on whether the pattern was created or matched. This is achieved with `ON -CREATE` and `ON MATCH` sub clauses. - -Example. Set a different properties depending on what `MERGE` did. - -```opencypher -MATCH (n :Person) MERGE (n)-[:FriendOf]->(m) -ON CREATE SET m.prop = "created" ON MATCH SET m.prop = "existed" -``` - -For more details, click [this -link](https://neo4j.com/docs/developer-manual/current/cypher/clauses/merge/). diff --git a/docs/user_technical/reference_guide/05_indexing.md b/docs/user_technical/reference_guide/05_indexing.md deleted file mode 100644 index dd8e074be..000000000 --- a/docs/user_technical/reference_guide/05_indexing.md +++ /dev/null @@ -1,56 +0,0 @@ -## Indexing - -An index stores additional information on certain types of data, so that -retrieving said data becomes more efficient. Downsides of indexing are: - - * requiring extra storage for each index and - * slowing down writes to the database. - -Carefully choosing which data to index can tremendously improve data retrieval -efficiency, and thus make index downsides negligible. - -Memgraph automatically indexes labeled data. This improves queries -which fetch nodes by label: - -```opencypher -MATCH (n :Label) ... RETURN n -``` - -Indexing can also be applied to data with a specific combination of label and -property. These are not automatically created, instead a user needs to create -them explicitly. Creation is done using a special -`CREATE INDEX ON :Label(property)` language construct. - -For example, to index nodes which is labeled as `:Person` and has a property -named `age`: - -```opencypher -CREATE INDEX ON :Person(age) -``` - -After the index is created, retrieving those nodes will become more efficient. -For example, the following query will retrieve all nodes which have an `age` -property, instead of fetching each `:Person` node and checking whether the -property exists. - -```opencypher -MATCH (n :Person {age: 42}) RETURN n -``` - -Using index based retrieval also works when filtering labels and properties -with `WHERE`. For example, the same effect as in the previous example can be -done with: - -```opencypher -MATCH (n) WHERE n:Person AND n.age = 42 RETURN n -``` - -Since the filter inside `WHERE` can contain any kind of an expression, the -expression can be complicated enough so that the index does not get used. We -are continuously improving the recognition of index usage opportunities from a -`WHERE` expression. If there is any suspicion that an index may not be used, -we recommend putting properties and labels inside the `MATCH` pattern. - -Currently, once an index is created it cannot be deleted. This feature will be -implemented very soon. The expected syntax for removing an index will be `DROP -INDEX ON :Label(property)`. diff --git a/docs/user_technical/reference_guide/06_graph-algorithms.md b/docs/user_technical/reference_guide/06_graph-algorithms.md deleted file mode 100644 index c15b3ed3e..000000000 --- a/docs/user_technical/reference_guide/06_graph-algorithms.md +++ /dev/null @@ -1,137 +0,0 @@ -## Graph Algorithms - -### Filtering Variable Length Paths - -OpenCypher supports only simple filtering when matching variable length paths. -For example: - -```opencypher -MATCH (n)-[edge_list:Type * {x: 42}]-(m) -``` - -This will produce only those paths whose edges have the required `Type` and `x` -property value. Edges that compose the produced paths are stored in a symbol -named `edge_list`. Naturally, the user could have specified any other symbol -name. - -Memgraph extends openCypher with a syntax for arbitrary filter expressions -during path matching. The next example filters edges which have property `x` -between `0` and `10`. - -```opencypher -MATCH (n)-[edge_list * (edge, node | 0 < edge.x < 10)]-(m) -``` - -Here we introduce a lambda function with parentheses, where the first two -arguments, `edge` and `node`, correspond to each edge and node during path -matching. `node` is the destination node we are moving to across the current -`edge`. The last `node` value will be the same value as `m`. Following the -pipe (`|`) character is an arbitrary expression which must produce a boolean -value. If `True`, matching continues, otherwise the path is discarded. - -The previous example can be written using the `all` function: - -```opencypher -MATCH (n)-[edge_list *]-(m) WHERE all(edge IN edge_list WHERE 0 < edge.x < 10) -``` - -However, filtering using a lambda function is more efficient because paths -may be discarded earlier in the traversal. Furthermore, it provides more -flexibility for deciding what kind of paths are matched due to more expressive -filtering capabilities. Therefore, filtering through lambda functions should -be preferred whenever possible. - -### Breadth First Search - -A typical graph use-case is searching for the shortest path between nodes. -The openCypher standard does not define this feature, so Memgraph provides -a custom implementation, based on the edge expansion syntax. - -Finding the shortest path between nodes can be done using breadth-first -expansion: - -```opencypher -MATCH (a {id: 723})-[edge_list:Type *bfs..10]-(b {id: 882}) RETURN * -``` - -The above query will find all paths of length up to 10 between nodes `a` and `b`. -The edge type and maximum path length are used in the same way like in variable -length expansion. - -To find only the shortest path, simply append `LIMIT 1` to the `RETURN` clause. - -```opencypher -MATCH (a {id: 723})-[edge_list:Type *bfs..10]-(b {id: 882}) RETURN * LIMIT 1 -``` - -Breadth-first expansion allows an arbitrary expression filter that determines -if an expansion is allowed. Following is an example in which expansion is -allowed only over edges whose `x` property is greater than `12` and nodes `y` -whose property is less than `3`: - -```opencypher -MATCH (a {id: 723})-[*bfs..10 (e, n | e.x > 12 AND n.y < 3)]-() RETURN * -``` - -The filter is defined as a lambda function over `e` and `n`, which denote the edge -and node being expanded over in the breadth first search. Note that if the user -omits the edge list symbol (`edge_list` in previous examples) it will not be included -in the result. - -There are a few benefits of the breadth-first expansion approach, as opposed to -a specialized `shortestPath` function. For one, it is possible to inject -expressions that filter on nodes and edges along the path itself, not just the final -destination node. Furthermore, it's possible to find multiple paths to multiple destination -nodes regardless of their length. Also, it is possible to simply go through a node's -neighbourhood in breadth-first manner. - -Currently, it isn't possible to get all shortest paths to a single node using -Memgraph's breadth-first expansion. - -### Weighted Shortest Path - -Another standard use-case in a graph is searching for the weighted shortest -path between nodes. The openCypher standard does not define this feature, so -Memgraph provides a custom implementation, based on the edge expansion syntax. - -Finding the weighted shortest path between nodes is done using the weighted -shortest path expansion: - -```opencypher -MATCH (a {id: 723})-[ - edge_list *wShortest 10 (e, n | e.weight) total_weight - ]-(b {id: 882}) -RETURN * -``` - -The above query will find the shortest path of length up to 10 nodes between -nodes `a` and `b`. The length restriction parameter is optional. - -Weighted Shortest Path expansion allows an arbitrary expression that determines -the weight for the current expansion. Total weight of a path is calculated as -the sum of all weights on the path between two nodes. Following is an example in -which the weight between nodes is defined as the product of edge weights -(instead of sum), assuming all weights are greater than '1': - -```opencypher -MATCH (a {id: 723})-[ - edge_list *wShortest 10 (e, n | log(e.weight)) total_weight - ]-(b {id: 882}) -RETURN exp(total_weight) -``` - -Weighted Shortest Path expansions also allows an arbitrary expression filter -that determines if an expansion is allowed. Following is an example in which -expansion is allowed only over edges whose `x` property is greater than `12` -and nodes `y` whose property is less than `3`: - -```opencypher -MATCH (a {id: 723})-[ - edge_list *wShortest 10 (e, n | e.weight) total_weight (e, n | e.x > 12 AND n.y < 3) - ]-(b {id: 882}) -RETURN exp(total_weight) -``` - -Both weight and filter expression are defined as lambda functions over `e` and -`n`, which denote the edge and the node being expanded over in the weighted -shortest path search. diff --git a/docs/user_technical/reference_guide/07_graph-streams.md b/docs/user_technical/reference_guide/07_graph-streams.md deleted file mode 100644 index d9187a950..000000000 --- a/docs/user_technical/reference_guide/07_graph-streams.md +++ /dev/null @@ -1,115 +0,0 @@ -## Graph Streams - -### Kafka - -Memgraphs custom openCypher clause for creating a stream is: -```opencypher -CREATE STREAM stream_name AS - LOAD DATA KAFKA 'URI' - WITH TOPIC 'topic' - WITH TRANSFORM 'URI' - [BATCH_INTERVAL milliseconds] - [BATCH_SIZE count] -``` -The `CREATE STREAM` clause happens in a transaction. - -`WITH TOPIC` parameter specifies the Kafka topic from which we'll stream -data. - -`WITH TRANSFORM` parameter should contain a URI of the transform script. -We cover more about the transform script later, in the [transform](#transform) -section. - -`BATCH_INTERVAL` parameter defines the time interval in milliseconds -which is the time between two successive stream importing operations. - -`BATCH_SIZE` parameter defines the count of Kafka messages that will be -batched together before import. - -If both `BATCH_INTERVAL` and `BATCH_SIZE` parameters are given, the condition -that is satisfied first will trigger the batched import. - -Default value for `BATCH_INTERVAL` is 100 milliseconds, and the default value -for `BATCH_SIZE` is 10. - -The `DROP` clause deletes a stream: -```opencypher -DROP STREAM stream_name; -``` - -The `SHOW` clause enables you to see all configured streams: -```opencypher -SHOW STREAMS; -``` - -You can also start/stop streams with the `START` and `STOP` clauses: -```opencypher -START STREAM stream_name [LIMIT count BATCHES]; -STOP STREAM stream_name; -``` -A stream needs to be stopped in order to start it and it needs to be started in -order to stop it. Starting a started or stopping a stopped stream will not -affect that stream. - -There are also convenience clauses to start and stop all streams: -```opencypher -START ALL STREAMS; -STOP ALL STREAMS; -``` - -Before the actual import, you can also test the stream with the `TEST -STREAM` clause: -```opencypher -TEST STREAM stream_name [LIMIT count BATCHES]; -``` -When a stream is tested, data extraction and transformation occurs, but nothing -is inserted into the graph. - -A stream needs to be stopped in order to test it. When the batch limit is -omitted, `TEST STREAM` will run for only one batch by default. - -#### Transform - -The transform script allows Memgraph users to have custom Kafka messages and -still be able to import data in Memgraph by adding the logic to decode the -messages in the transform script. - -The entry point of the transform script from Memgraph is the `stream` function. -Input for the `stream` function is a list of bytes that represent byte encoded -Kafka messages, and the output of the `stream` function must be a list of -tuples containing openCypher string queries and corresponding parameters stored -in a dictionary. - -To be more precise, the signature of the `stream` function looks like the -following: - -```plaintext -stream : [bytes] -> [(str, {str : type})] -type : none | bool | int | float | str | list | dict -``` - -An example of a simple transform script that creates vertices if the message -contains one number (the vertex id) or it creates edges if the message contains -two numbers (origin vertex id and destination vertex id) would look like the -following: - -```python -def create_vertex(vertex_id): - return ("CREATE (:Node {id: $id})", {"id": vertex_id}) - - -def create_edge(from_id, to_id): - return ("MATCH (n:Node {id: $from_id}), (m:Node {id: $to_id}) "\ - "CREATE (n)-[:Edge]->(m)", {"from_id": from_id, "to_id": to_id}) - - -def stream(batch): - result = [] - for item in batch: - message = item.decode('utf-8').split() - if len(message) == 1: - result.append(create_vertex(message[0])) - elif len(message) == 2: - result.append(create_edge(message[0], message[1])) - return result -``` diff --git a/docs/user_technical/reference_guide/08_security.md b/docs/user_technical/reference_guide/08_security.md deleted file mode 100644 index 51cd949a4..000000000 --- a/docs/user_technical/reference_guide/08_security.md +++ /dev/null @@ -1,125 +0,0 @@ -## Security - -Before reading this article we highly recommend going through a how-to guide -on [managing user privileges](../how_to_guides/05_manage-user-privileges.md) -which contains more thorough explanations of the concepts behind `openCypher` -commands listed in this article. - -### Users - -Creating a user can be done by executing the following command: - -```openCypher - CREATE USER user_name [IDENTIFIED BY 'password']; -``` -If the user should authenticate themself on each session, i.e. provide their -password on each session, the part within the brackets is mandatory. Otherwise, -the password is set to `null` and the user will be allowed to log-in using -any password provided that they provide the correct username. - -You can also set or alter a user's password anytime by issuing the following -command: - -```openCypher - SET PASSWORD FOR user_name TO 'new_password'; -``` - -Removing a user's password, i.e. allowing the user to log-in using any -password can be done by setting it to `null` as follows: - -```openCypher - SET PASSWORD FOR user_name TO null; -``` - -### User Roles - -Each user can be assigned at most one user role. One can think of user roles -as abstractions which capture the privilege levels of a set of users. For -example, suppose that `Dominik` and `Marko` belong to upper management of -a certain company. It makes sense to grant them a set of privileges that other -users are not entitled to so, instead of granting those privileges to each -of them, we can create a role with those privileges called `manager` -which we assign to `Dominik` and `Marko`. - -In other words, Each privilege that is granted to a user role is automatically -granted to a user (unless it has been explicitly denied to that user). -Similarly, each privilege that is denied to a user role is automatically denied -to a user (even if it has been explicitly granted to that user). - -Creating a user role can be done by executing the following command: - -```openCypher - CREATE ROLE role_name; -``` - -Assigning a user role to a certain user can be done by the following command: - -```openCypher - SET ROLE FOR user_name TO role_name; -``` - -Removing the role from the user can be done by: - -```openCypher - CLEAR ROLE FOR user_name; -``` - -Finally, showing all users that have a certain role can be done as: - -```openCypher - SHOW USERS FOR role_name; -``` - -Similarly, querying which role a certain user has can be done as: - -```openCypher - SHOW ROLE FOR user_name; -``` - -### Privileges - -At the moment, privileges are confined to users' abilities to perform certain -`OpenCypher` queries. Namely users can be given permission to execute a subset -of the following commands: `CREATE`, `DELETE`, `MATCH`, `MERGE`, `SET`, -`REMOVE`, `INDEX`, `AUTH`, `STREAM`. - -Granting a certain set of privileges to a specific user or user role can be -done by issuing the following command: - -```openCypher - GRANT privilege_list TO user_or_role; -``` - -For example, granting `AUTH` and `STREAM` privileges to users with the role -`moderator` would be written as: - -```openCypher - GRANT AUTH, STREAM TO moderator: -``` - -Similarly, denying privileges is done using the `DENY` keyword instead of -`GRANT`. - -Both denied and granted privileges can be revoked, meaning that their status is -not defined for that user or role. Revoking is done using the `REVOKE` keyword. -The users should note that, although semantically unintuitive, the level of a -certain privilege can be raised by using `REVOKE`. For instance, suppose a user -has been denied a `STREAM` privilege, but the role it belongs to is granted -that privilege. Currently, the user is unable to use data streaming features, -but, after revoking the user's `STREAM` privilege, they will be able to do so. - -Finally, if you wish to grant, deny or revoke all privileges and find it tedious -to explicitly list them, you can use the `ALL PRIVILEGES` construct instead. -For example, revoking all privileges from user `jdoe` can be done with the -following command: - -```openCypher - REVOKE ALL PRIVILEGES FROM jdoe; -``` - -Finally, obtaining the status of each privilege for a certain user or role can be -done by issuing the following command: - -```openCypher - SHOW PRIVILEGES FOR user_or_role; -``` diff --git a/docs/user_technical/reference_guide/09_dynamic-graph-partitioner.md b/docs/user_technical/reference_guide/09_dynamic-graph-partitioner.md deleted file mode 100644 index 686faf2b3..000000000 --- a/docs/user_technical/reference_guide/09_dynamic-graph-partitioner.md +++ /dev/null @@ -1,9 +0,0 @@ -## Dynamic Graph Partitioner - -Memgraph supports dynamic graph partitioning which dynamically improves -performance on badly partitioned dataset over workers. To enable it, the user -should use the following flag when firing up the *master* node: - -```plaintext ---dynamic_graph_partitioner_enable -``` diff --git a/docs/user_technical/reference_guide/10_other-features.md b/docs/user_technical/reference_guide/10_other-features.md deleted file mode 100644 index 71ef618d7..000000000 --- a/docs/user_technical/reference_guide/10_other-features.md +++ /dev/null @@ -1,160 +0,0 @@ -## Other Features - -The following sections describe some of the other supported features. - -### UNWIND - -The `UNWIND` clause is used to unwind a list of values as individual rows. - -Example. Produce rows out of a single list. - -```opencypher -UNWIND [1,2,3] AS listElement RETURN listElement -``` - -More examples are -[here](https://neo4j.com/docs/developer-manual/current/cypher/clauses/unwind/). - -### Functions - -This section contains the list of other supported functions. - - Name | Description ------------------|------------ - `coalesce` | Returns the first non null argument. - `startNode` | Returns the starting node of an edge. - `endNode` | Returns the destination node of an edge. - `degree` | Returns the number of edges (both incoming and outgoing) of a node. - `head` | Returns the first element of a list. - `last` | Returns the last element of a list. - `properties` | Returns the properties of a node or an edge. - `size` | Returns the number of elements in a list or a map. When given a string it returns the number of characters. When given a path it returns the number of expansions (edges) in that path. - `toBoolean` | Converts the argument to a boolean. - `toFloat` | Converts the argument to a floating point number. - `toInteger` | Converts the argument to an integer. - `type` | Returns the type of an edge as a character string. - `keys` | Returns a list keys of properties from an edge or a node. Each key is represented as a string of characters. - `labels` | Returns a list of labels from a node. Each label is represented as a character string. - `nodes` | Returns a list of nodes from a path. - `relationships` | Returns a list of relationships (edges) from a path. - `range` | Constructs a list of value in given range. - `tail` | Returns all elements after the first of a given list. - `abs` | Returns the absolute value of a number. - `ceil` | Returns the smallest integer greater than or equal to given number. - `floor` | Returns the largest integer smaller than or equal to given number. - `round` | Returns the number, rounded to the nearest integer. Tie-breaking is done using the *commercial rounding*, where -1.5 produces -2 and 1.5 produces 2. - `exp` | Calculates `e^n` where `e` is the base of the natural logarithm, and `n` is the given number. - `log` | Calculates the natural logarithm of a given number. - `log10` | Calculates the logarithm (base 10) of a given number. - `sqrt` | Calculates the square root of a given number. - `acos` | Calculates the arccosine of a given number. - `asin` | Calculates the arcsine of a given number. - `atan` | Calculates the arctangent of a given number. - `atan2` | Calculates the arctangent2 of a given number. - `cos` | Calculates the cosine of a given number. - `sin` | Calculates the sine of a given number. - `tan` | Calculates the tangent of a given number. - `sign` | Applies the signum function to a given number and returns the result. The signum of positive numbers is 1, of negative -1 and for 0 returns 0. - `e` | Returns the base of the natural logarithm. - `pi` | Returns the constant *pi*. - `rand` | Returns a random floating point number between 0 (inclusive) and 1 (exclusive). - `startsWith` | Check if the first argument starts with the second. - `endsWith` | Check if the first argument ends with the second. - `contains` | Check if the first argument has an element which is equal to the second argument. - `left` | Returns a string containing the specified number of leftmost characters of the original string. - `lTrim` | Returns the original string with leading whitespace removed. - `replace` | Returns a string in which all occurrences of a specified string in the original string have been replaced by another (specified) string. - `reverse` | Returns a string in which the order of all characters in the original string have been reversed. - `right` | Returns a string containing the specified number of rightmost characters of the original string. - `rTrim` | Returns the original string with trailing whitespace removed. - `split` | Returns a list of strings resulting from the splitting of the original string around matches of the given delimiter. - `substring` | Returns a substring of the original string, beginning with a 0-based index start and length. - `toLower` | Returns the original string in lowercase. - `toString` | Converts an integer, float or boolean value to a string. - `toUpper` | Returns the original string in uppercase. - `trim` | Returns the original string with leading and trailing whitespace removed. - `all` | Check if all elements of a list satisfy a predicate.
The syntax is: `all(variable IN list WHERE predicate)`.
NOTE: Whenever possible, use Memgraph's lambda functions when matching instead. - `single` | Check if only one element of a list satisfies a predicate.
The syntax is: `single(variable IN list WHERE predicate)`. - `reduce` | Accumulate list elements into a single result by applying an expression. The syntax is:
`reduce(accumulator = initial_value, variable IN list | expression)`. - `extract` | A list of values obtained by evaluating an expression for each element in list. The syntax is:
`extract(variable IN list | expression)`. - `assert` | Raises an exception reported to the client if the given argument is not `true`. - `counter` | Generates integers that are guaranteed to be unique on the database level, for the given counter name. - `counterSet` | Sets the counter with the given name to the given value. - `indexInfo` | Returns a list of all the indexes available in the database. The list includes indexes that are not yet ready for use (they are concurrently being built by another transaction). - `timestamp` | Returns the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC. - `id` | Returns identifier for a given node or edge. The identifier is generated during the initialization of node or edge and will be persisted through the durability mechanism. - -### String Operators - -Apart from comparison and concatenation operators openCypher provides special -string operators for easier matching of substrings: - -Operator | Description --------------------|------------ - `a STARTS WITH b` | Returns true if prefix of string a is equal to string b. - `a ENDS WITH b` | Returns true if suffix of string a is equal to string b. - `a CONTAINS b` | Returns true if some substring of string a is equal to string b. - -### Parameters - -When automating the queries for Memgraph, it comes in handy to change only -some parts of the query. Usually, these parts are values which are used for -filtering results or similar, while the rest of the query remains the same. - -Parameters allow reusing the same query, but with different parameter values. -The syntax uses the `$` symbol to designate a parameter name. We don't allow -old Cypher parameter syntax using curly braces. For example, you can parameterize -filtering a node property: - -```opencypher -MATCH (node1 {property: $propertyValue}) RETURN node1 -``` - -You can use parameters instead of any literal in the query, but not instead of -property maps even though that is allowed in standard openCypher. Following -example is illegal in Memgraph: - -```opencypher -MATCH (node1 $propertyValue) RETURN node1 -``` - -To use parameters with Python driver use following syntax: - -```python -session.run('CREATE (alice:Person {name: $name, age: $ageValue}', - name='Alice', ageValue=22)).consume() -``` - -To use parameters which names are integers you will need to wrap parameters in -a dictionary and convert them to strings before running a query: - -```python -session.run('CREATE (alice:Person {name: $0, age: $1}', - {'0': "Alice", '1': 22})).consume() -``` - -To use parameters with some other driver please consult appropriate -documentation. - -### CASE - -Conditional expressions can be expressed in openCypher language by simple and -generic form of `CASE` expression. A simple form is used to compare an expression -against multiple predicates. For the first matched predicate result of the -expression provided after the `THEN` keyword is returned. If no expression is -matched value following `ELSE` is returned is provided, or `null` if `ELSE` is not -used: - -```opencypher -MATCH (n) -RETURN CASE n.currency WHEN "DOLLAR" THEN "$" WHEN "EURO" THEN "€" ELSE "UNKNOWN" END -``` - -In generic form, you don't need to provide an expression whose value is compared to -predicates, but you can list multiple predicates and the first one that evaluates -to true is matched: - -```opencypher -MATCH (n) -RETURN CASE WHEN n.height < 30 THEN "short" WHEN n.height > 300 THEN "tall" END -``` diff --git a/docs/user_technical/reference_guide/11_differences.md b/docs/user_technical/reference_guide/11_differences.md deleted file mode 100644 index 8033b40d4..000000000 --- a/docs/user_technical/reference_guide/11_differences.md +++ /dev/null @@ -1,63 +0,0 @@ -## Differences - -Although we try to implement openCypher query language as closely to the -language reference as possible, we had to make some changes to enhance the -user experience. - -### Symbolic Names - -We don't allow symbolic names (variables, label names...) to be openCypher -keywords (WHERE, MATCH, COUNT, SUM...). - -### Unicode Codepoints in String Literal - -Use `\u` followed by 4 hex digits in string literal for UTF-16 codepoint and -`\U` with 8 hex digits for UTF-32 codepoint in Memgraph. - - -### Difference from Neo4j's Cypher Implementation - -The openCypher initiative stems from Neo4j's Cypher query language. Following is a list -of most important differences between Neo's Cypher and Memgraph's openCypher implementation, -for users that are already familiar with Neo4j. There might be other differences not documented -here (especially subtle semantic ones). - -#### Unsupported Constructs - -* Data importing. Memgraph doesn't support Cypher's CSV importing capabilities. -* The `FOREACH` language construct for performing an operation on every list element. -* The `CALL` construct for a standalone function call. This can be expressed using - `RETURN functioncall()`. For example, with Memgraph you can get information about - the indexes present in the database using the `RETURN indexinfo()` openCypher query. -* Stored procedures. -* Regular expressions for string matching. -* `shortestPath` and `allShortestPaths` functions. `shortestPath` can be expressed using - Memgraph's breadth-first expansion syntax already described in this document. -* Patterns in expressions. For example, Memgraph doesn't support `size((n)-->())`. Most of the time - the same functionalities can be expressed differently in Memgraph using `OPTIONAL` expansions, - function calls etc. -* Map projections such as `MATCH (n) RETURN n {.property1, .property2}`. - -#### Unsupported Functions - -General purpose functions: - -* `exists(n.property)` - This can be expressed using `n.property IS NOT NULL`. -* `length()` is named `size()` in Memgraph. - -Aggregation functions: - -* `count(DISTINCT variable)` - This can be expressed using `WITH DISTINCT variable RETURN count(variable)`. - -Mathematical functions: - -* `percentileDisc()` -* `stDev()` -* `point()` -* `distance()` -* `degrees()` - -List functions: - -* `any()` -* `none()` diff --git a/docs/user_technical/tutorials/01_tutorials-overview.md b/docs/user_technical/tutorials/01_tutorials-overview.md deleted file mode 100644 index 31381eeac..000000000 --- a/docs/user_technical/tutorials/01_tutorials-overview.md +++ /dev/null @@ -1,14 +0,0 @@ -## Tutorials Overview - -Articles within the tutorials section serve as real-world examples of using -Memgraph. These articles tend to provide the user with a reasonably-sized -dataset and some example queries that showcase how to use Memgraph on that -particular dataset. We encourage all Memgraph users to go through at least -one of the tutorials as they can also serve as a verification that Memgraph -is successfully installed on your system. - -So far we have covered the following topics: - - * [Analyzing TED Talks](02_analyzing-TED-talks.md) - * [Graphing the Premier League](03_graphing-the-premier-league.md) - * [Exploring the European Road Network](04_exploring-the-european-road-network.md) diff --git a/docs/user_technical/tutorials/02_analyzing-TED-talks.md b/docs/user_technical/tutorials/02_analyzing-TED-talks.md deleted file mode 100644 index 3ad37b2bb..000000000 --- a/docs/user_technical/tutorials/02_analyzing-TED-talks.md +++ /dev/null @@ -1,176 +0,0 @@ -## 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](04_exploring-the-european-road-network.md) - * [Graphing the Premier League](03_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 — 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; -``` diff --git a/docs/user_technical/tutorials/03_graphing-the-premier-league.md b/docs/user_technical/tutorials/03_graphing-the-premier-league.md deleted file mode 100644 index 4945ae684..000000000 --- a/docs/user_technical/tutorials/03_graphing-the-premier-league.md +++ /dev/null @@ -1,190 +0,0 @@ -## 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](02_analyzing-TED-talks.md) - * [Exploring the European Road Network](04_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—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—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; -``` diff --git a/docs/user_technical/tutorials/04_exploring-the-european-road-network.md b/docs/user_technical/tutorials/04_exploring-the-european-road-network.md deleted file mode 100644 index 4f6866b82..000000000 --- a/docs/user_technical/tutorials/04_exploring-the-european-road-network.md +++ /dev/null @@ -1,178 +0,0 @@ -## 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](02_analyzing-TED-talks.md) - * [Graphing the Premier League](03_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) diff --git a/docs/user_technical/upcoming-features.md b/docs/user_technical/upcoming-features.md deleted file mode 100644 index 2565928fe..000000000 --- a/docs/user_technical/upcoming-features.md +++ /dev/null @@ -1,61 +0,0 @@ -## Upcoming Features - -This chapter describes some of the planned features, that we at Memgraph are -working on. - -### Performance Improvements - -Excellent database performance is one of Memgraph's long-standing goals. We -will be continually working on improving the performance. This includes: - - * query compilation; - * query execution; - * core engine performance; - * algorithmic improvements (i.e. bidirectional breadth-first search); - * memory usage and - * other improvements. - -### Label-Property Index Usage Improvements - -Currently, indexing combinations of labels and properties can be created, but -cannot be deleted. We plan to add a new query language construct which will -allow deletion of created indices. - -### Improving openCypher Support - -Although we have implemented the most common features of the openCypher query -language, there are other useful features we are still working on. - -#### Functions - -Memgraph's openCypher implementation supports the most useful functions, but -there are more which openCypher provides. Some are related to not yet -implemented features like paths, while some may use the features Memgraph -already supports. Out of the remaining functions, some are more useful than -others and as such they will be supported sooner. - -#### List Comprehensions - -List comprehensions are similar to the supported `collect` function, which -generates a list out of multiple values. But unlike `collect`, list -comprehensions offer a powerful mechanism for filtering or otherwise -manipulating values which are collected into a list. - -For example, getting numbers between 0 and 10 and squaring them: - -```opencypher -RETURN [x IN range(0, 10) | x^2] AS squares -``` - -Another example, to collect `:Person` nodes with `age` less than 42, without -list comprehensions can be achieved with: - -```opencypher -MATCH (n :Person) WHERE n.age < 42 RETURN collect(n) -``` - -Using list comprehensions, the same can be done with the query: - -```opencypher -MATCH (n :Person) RETURN [n IN collect(n) WHERE n.age < 42] -```