From c69fe776dcd33eb3be0f3572ee999eb92cfb9cd5 Mon Sep 17 00:00:00 2001 From: Daniel Hofer Date: Wed, 21 Apr 2021 15:55:02 +0200 Subject: [PATCH] Bugfixes, improvements, a meaningful commit message, A README FILE --- README.md | 30 ++ frontend/src/app/app.component.html | 79 ++- .../components/browser/browser.component.html | 2 +- frontend/src/index.html | 2 +- pom.xml | 6 - .../repository/CsvPokemonRepositoryImpl.java | 8 +- .../repository/CsvTypeRepositoryImpl.java | 22 +- .../repository/GenericCsvRepositoryImpl.java | 16 +- .../jku/faw/neo4jdemo/runner/Neo4JRunner.java | 23 +- src/main/resources/static/index.html | 2 +- src/main/resources/static/main.js | 489 +++++++++++------- src/main/resources/static/main.js.map | 2 +- 12 files changed, 443 insertions(+), 238 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..8bb1f29 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Neo4JDemo +This project is used for a lecture at the Johannes Kepler University Linz (JKU) in Austria. +You are free to using it also if you do not participate in the course. + +--- + +## Running +ATTENTION: This application tries to create the subfolder 'database' in the working directory. +If a folder of the same name is already present, the application will abort. +Otherwise, the folder is deleted on application shutdown. + +### Requirements +- Java 11 or above +- A folder without 'database' in it + +### Running from the console +1. Download the latest release at the releases page https://github.com/dahoat/neo4jdemo/releases +1. Open a cmd/terminal/... and navigate to the JAR file +1. Make sure no directory 'database' is present in the current directory +1. Execute `java --illegal-access=permit -jar neo4jdemo.jar` +1. Navigate to http://localhost:8080/ +1. When you are finished, click into the console and press [Ctrl]+[C] to shutdown the application +1. Cleanup 'database' in case of an error. + +### Running from your IDE +Clone the project and set up the Spring Boot Application. +The Angular project located in the folder 'frontend' is only needed, if you would like to change the website with the examples. +In that case, you have to use the command `ng build-spring` which will compile the angular project and store the result in 'resources/static' in the Spring project. + +--- diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html index 1ce9661..d53df88 100644 --- a/frontend/src/app/app.component.html +++ b/frontend/src/app/app.component.html @@ -35,6 +35,77 @@

Basic building blocks

Official Cypher Manual

https://neo4j.com/docs/cypher-manual/current/ +

Creating our First Entries

+ +
+ We will start by creating our first node + + This only inserts an empty node into the database without a label or any content. +
+ +
+ So next, we create a node with the label Student and a name. + + This time, the node is stored in the variable n, so we can RETURN it at the end of the query. +
+ +
+ We now also want to add a property study to our student. + What we need is to first get the node out of the database again using MATCH like this: + + If this query returns our previously created node, we can enhance the query. + + This gets the node out of the database, modifies it by adding the property study and then returns the modified version back to us. +
+ +
+ We still have the empty node in the database which we do not need any longer, so we want to remove it. + First, we have to make sure, we get match only the node we want to delete: + + This has the problem that we also get our students, so we need to filter them out: + + We could also do this one for the case we have multiple labels in the database: + + For the actual deletion, we replace the RETURN part with DELETE: + +
+ +
+ To add some edges, we need more nodes, so we create a lecture, find our student and attach both with an edge. + +
+ +
+ After Alex graduated, the nodes is eventually removed, so we try this query: + + Which won't execute because as Neo4J says Cannot delete node<0>, because it still has relationships. To delete this node, you must first delete its relationships. + Instead, we exlicilty need to state that we want also the relationships removed by + +
+ +
+ Sometimes, we want a node, but are not sure, whether it is already existing. + For this case, we can use MERGE which tries to lookup a node and nothing is found, creates it as if CREATE was used. + For example, to add another student to our (existing) lecture: + + ATTENTION: If we used + + We would have got another lecture about graph databases because Neo4J would be looking for a lecture with an incoming LISTENS edge attaching a student named Kim. + Actually if you use the second query, change the name and execute it, you would end up with another new lecture with only one student. +
+ +
+ To remove a property of a node, REMOVE is used and not DELETE. + +
+ +
+ At this point, we finished the basics of creating and deleting nodes and edges and now focus on fetching data. + Before that, we can clean up the database, either by + + Matching, detaching and deleting everything in the database, or simply use the button below. + +

Simple MATCH queries

@@ -108,9 +179,9 @@

Filtering with Properties

We can also filter using all kinds of functions and combinations. - - - + + +

Filtering with Paths

@@ -146,7 +217,7 @@

Filtering with Paths

For Pokemon with three evolutionary levels, we can use an abbreviation: - + Where we do not see the full path but only start end end. If we again store the paths in a variable, we get all three Pokemon. diff --git a/frontend/src/app/components/browser/browser.component.html b/frontend/src/app/components/browser/browser.component.html index 068018e..7c33146 100644 --- a/frontend/src/app/components/browser/browser.component.html +++ b/frontend/src/app/components/browser/browser.component.html @@ -14,5 +14,5 @@

Neo4J Browser

Password
<empty>
- Basically, just click + Basically, just enter localhost in the URL and click
diff --git a/frontend/src/index.html b/frontend/src/index.html index 3af61ec..cb10adf 100644 --- a/frontend/src/index.html +++ b/frontend/src/index.html @@ -2,7 +2,7 @@ - Frontend + Neo4JDemo - Control Panel diff --git a/pom.xml b/pom.xml index e2be51c..d69ad7e 100644 --- a/pom.xml +++ b/pom.xml @@ -26,12 +26,6 @@ spring-boot-starter-web - - org.springframework.boot - spring-boot-devtools - runtime - true - org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/at/jku/faw/neo4jdemo/repository/CsvPokemonRepositoryImpl.java b/src/main/java/at/jku/faw/neo4jdemo/repository/CsvPokemonRepositoryImpl.java index a8f2c1d..22bae3d 100644 --- a/src/main/java/at/jku/faw/neo4jdemo/repository/CsvPokemonRepositoryImpl.java +++ b/src/main/java/at/jku/faw/neo4jdemo/repository/CsvPokemonRepositoryImpl.java @@ -1,6 +1,9 @@ package at.jku.faw.neo4jdemo.repository; import at.jku.faw.neo4jdemo.model.csv.CsvPokemon; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Repository; import java.io.IOException; @@ -12,8 +15,9 @@ public class CsvPokemonRepositoryImpl extends GenericCsvRepositoryImpl implement private final List csvPokemon = new ArrayList<>(); - public CsvPokemonRepositoryImpl() throws IOException { - csvPokemon.addAll(getCsvEntities("data/pokemon_species.csv", CsvPokemon.class)); + public CsvPokemonRepositoryImpl(ResourceLoader resourceLoader) throws IOException { + Resource csvFile = resourceLoader.getResource("classpath:data/pokemon_species.csv"); + csvPokemon.addAll(getCsvEntities(csvFile, CsvPokemon.class)); } @Override diff --git a/src/main/java/at/jku/faw/neo4jdemo/repository/CsvTypeRepositoryImpl.java b/src/main/java/at/jku/faw/neo4jdemo/repository/CsvTypeRepositoryImpl.java index 12a88cc..24c1f08 100644 --- a/src/main/java/at/jku/faw/neo4jdemo/repository/CsvTypeRepositoryImpl.java +++ b/src/main/java/at/jku/faw/neo4jdemo/repository/CsvTypeRepositoryImpl.java @@ -2,21 +2,12 @@ import at.jku.faw.neo4jdemo.model.csv.CsvType; import at.jku.faw.neo4jdemo.model.csv.CsvTypeMapping; -import com.opencsv.CSVReader; -import com.opencsv.bean.CsvToBean; -import com.opencsv.bean.CsvToBeanBuilder; -import com.opencsv.bean.HeaderColumnNameMappingStrategy; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Repository; -import org.springframework.util.ResourceUtils; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStreamReader; import java.util.HashSet; -import java.util.List; import java.util.Set; @Repository @@ -25,9 +16,12 @@ public class CsvTypeRepositoryImpl extends GenericCsvRepositoryImpl implements C private final Set typeMappings = new HashSet<>(); private final Set types = new HashSet<>(); - public CsvTypeRepositoryImpl() throws IOException { - this.typeMappings.addAll(getCsvEntities("data/pokemon_types.csv", CsvTypeMapping.class)); - this.types.addAll(getCsvEntities("data/types.csv", CsvType.class)); + public CsvTypeRepositoryImpl(ResourceLoader resourceLoader) throws IOException { + Resource csvPokemonTypesResource = resourceLoader.getResource("classpath:data/pokemon_types.csv"); + Resource csvTypesResource = resourceLoader.getResource("classpath:data/types.csv"); + + this.typeMappings.addAll(getCsvEntities(csvPokemonTypesResource, CsvTypeMapping.class)); + this.types.addAll(getCsvEntities(csvTypesResource, CsvType.class)); } @Override diff --git a/src/main/java/at/jku/faw/neo4jdemo/repository/GenericCsvRepositoryImpl.java b/src/main/java/at/jku/faw/neo4jdemo/repository/GenericCsvRepositoryImpl.java index e646720..3f28361 100644 --- a/src/main/java/at/jku/faw/neo4jdemo/repository/GenericCsvRepositoryImpl.java +++ b/src/main/java/at/jku/faw/neo4jdemo/repository/GenericCsvRepositoryImpl.java @@ -1,30 +1,20 @@ package at.jku.faw.neo4jdemo.repository; -import at.jku.faw.neo4jdemo.model.csv.CsvType; import com.opencsv.CSVReader; import com.opencsv.bean.CsvToBean; import com.opencsv.bean.CsvToBeanBuilder; -import com.opencsv.bean.CsvToBeanFilter; import com.opencsv.bean.HeaderColumnNameMappingStrategy; import com.opencsv.enums.CSVReaderNullFieldIndicator; -import org.springframework.util.ResourceUtils; +import org.springframework.core.io.Resource; import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; -import java.util.Arrays; import java.util.List; public abstract class GenericCsvRepositoryImpl { - private File getCsvFile(String path) throws FileNotFoundException { - return ResourceUtils.getFile("classpath:" + path); - } - - protected List getCsvEntities(String csvFilePath, Class entity) throws IOException { - try(CSVReader reader = new CSVReader(new BufferedReader(new InputStreamReader(new FileInputStream(getCsvFile(csvFilePath)))))) { + protected List getCsvEntities(Resource csvResource, Class entity) throws IOException { + try(CSVReader reader = new CSVReader(new BufferedReader(new InputStreamReader(csvResource.getInputStream())))) { HeaderColumnNameMappingStrategy ms = new HeaderColumnNameMappingStrategy<>(); ms.setType(entity); diff --git a/src/main/java/at/jku/faw/neo4jdemo/runner/Neo4JRunner.java b/src/main/java/at/jku/faw/neo4jdemo/runner/Neo4JRunner.java index 9bc3fd7..3ad3476 100644 --- a/src/main/java/at/jku/faw/neo4jdemo/runner/Neo4JRunner.java +++ b/src/main/java/at/jku/faw/neo4jdemo/runner/Neo4JRunner.java @@ -9,7 +9,6 @@ import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; -import org.springframework.util.ResourceUtils; import javax.annotation.PreDestroy; import java.io.File; @@ -21,15 +20,20 @@ public class Neo4JRunner implements ApplicationRunner { private static final Logger logger = LoggerFactory.getLogger(Neo4JRunner.class); + private boolean cleanup = false; private File dbDir; private DatabaseManagementService dbms; @Override public void run(ApplicationArguments args) throws Exception { dbDir = new File("database"); - if (!dbDir.exists()) { - Files.createDirectory(dbDir.toPath()); + if (dbDir.exists()) { + logger.error("The directory 'database' already exists. This application deletes this folder on shutdown. If it is your folder, move it somewhere else, if it belongs to a previous execution of this application, delete it."); + System.exit(1); + return; } + cleanup = true; + Files.createDirectory(dbDir.toPath()); logger.warn("Database location is {}", dbDir.toPath().toAbsolutePath()); @@ -41,13 +45,22 @@ public void run(ApplicationArguments args) throws Exception { if(db.isAvailable(10*1000)) { logger.info("Neo4J is now available."); } + logger.warn("Press [CTRL]+[C] to shutdown."); } @PreDestroy public void onExit() { - logger.warn("Shutting database down."); - dbms.shutdown(); + if (!cleanup) { + return; + } + + try { + logger.warn("Shutting database down."); + dbms.shutdown(); + } catch (Exception e) { + e.printStackTrace(); + } logger.warn("Deleting database directory."); try { diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 4aec99c..4a360c6 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -2,7 +2,7 @@ - Frontend + Neo4JDemo - Control Panel diff --git a/src/main/resources/static/main.js b/src/main/resources/static/main.js index fddab0d..2592b27 100644 --- a/src/main/resources/static/main.js +++ b/src/main/resources/static/main.js @@ -30,7 +30,7 @@ class BrowserComponent { } } BrowserComponent.ɵfac = function BrowserComponent_Factory(t) { return new (t || BrowserComponent)(); }; -BrowserComponent.ɵcmp = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({ type: BrowserComponent, selectors: [["app-browser"]], decls: 25, vars: 0, consts: [["href", "http://localhost:8080/browser/index.html", "target", "_blank"], ["onclick", "alert('Not here, in the Neo4J Browser...');"]], template: function BrowserComponent_Template(rf, ctx) { if (rf & 1) { +BrowserComponent.ɵcmp = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({ type: BrowserComponent, selectors: [["app-browser"]], decls: 28, vars: 0, consts: [["href", "http://localhost:8080/browser/index.html", "target", "_blank"], ["onclick", "alert('Not here, in the Neo4J Browser...');"]], template: function BrowserComponent_Template(rf, ctx) { if (rf & 1) { _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "h2"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1, "Neo4J Browser"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); @@ -64,9 +64,13 @@ BrowserComponent.ɵcmp = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineC _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](21, ""); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](22, " Basically, just click "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](23, "button", 1); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](24, "Connect"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](22, " Basically, just enter "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](23, "em"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](24, "localhost"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](25, " in the URL and click "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](26, "button", 1); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](27, "Connect"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); } }, styles: ["dt[_ngcontent-%COMP%] {\n font-weight: bold;\n}\n\ndd[_ngcontent-%COMP%] {\n margin-bottom: 10px;\n}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImJyb3dzZXIuY29tcG9uZW50LmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLGlCQUFpQjtBQUNuQjs7QUFFQTtFQUNFLG1CQUFtQjtBQUNyQiIsImZpbGUiOiJicm93c2VyLmNvbXBvbmVudC5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyJkdCB7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xufVxuXG5kZCB7XG4gIG1hcmdpbi1ib3R0b206IDEwcHg7XG59XG4iXX0= */"] }); @@ -366,7 +370,7 @@ class AppComponent { } } AppComponent.ɵfac = function AppComponent_Factory(t) { return new (t || AppComponent)(); }; -AppComponent.ɵcmp = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({ type: AppComponent, selectors: [["app-root"]], decls: 199, vars: 0, consts: [["color", "primary"], [1, "content"], [1, "lecture-part"], ["query", "()", "copy", "false"], ["query", "[]", "copy", "false"], ["query", "-- -> <-", "copy", "false"], ["query", ":Label1 :Label1:Label2 :LABEL_FOR_AN_EDGE"], ["href", "https://neo4j.com/docs/cypher-manual/current/", "target", "_blank"], ["button", "pokemon"], ["query", "MATCH (node) RETURN node LIMIT 25"], ["query", "MATCH (pokemon:Pokemon) RETURN pokemon LIMIT 25"], ["query", "MATCH (t:Type) RETURN t"], ["query", "MATCH (p:Pokemon), (t:Type) RETURN p, t LIMIT 25"], ["query", "MATCH (p:Pokemon)-[:HAS_TYPE]-(t:Type) RETURN p, t LIMIT 25"], ["query", "MATCH (p:Pokemon)-[:HAS_TYPE]-(t:Type) RETURN * LIMIT 25"], ["query", "MATCH (p:Legendary) RETURN p"], ["query", "MATCH (p:Pokemon:Legendary) RETURN p"], ["query", "MATCH (p:Legendary:Pokemon) RETURN p"], ["query", "MATCH (p:Pokemon) WHERE p.name = 'pikachu' RETURN p"], ["query", "MATCH (p:Pokemon{name: 'pikachu'}) RETURN *"], ["copy", "false", "query", "MATCH (n) WHERE id(n) = 42 RETURN n"], ["query", "MATCH (n:Pokemon) WHERE n.name starts with 'pi' RETURN n"], ["query", "MATCH (n:Pokemon) WHERE n.name starts with 'pi' or n.name = 'charizard' RETURN n"], ["query", "MATCH (n:Pokemon) WHERE n.name starts with 'c' and n.pokedexId <= 150 RETURN n"], ["query", "MATCH (p:Pokemon)-[:HAS_TYPE]-(:Type{name: 'fire'}) WHERE p.pokedexId <= 150 RETURN *"], ["query", "MATCH (p:Pokemon)-[:HAS_TYPE{slot: 2}]-(t:Type) WHERE t.name = 'fire' RETURN *"], ["query", "MATCH (p:Pokemon) WHERE NOT (p)-[:EVOLVES_TO]->() RETURN p LIMIT 25"], ["query", "MATCH chain=(p1:Pokemon)-[:EVOLVES_TO]->(p2:Pokemon) WHERE NOT (p2)-[:EVOLVES_TO]->() RETURN chain"], ["query", "MATCH (p1:Pokemon)-[:EVOLVES_TO*3]->(p3:Pokemon) WHERE NOT (p3)-[:EVOLVES_TO]->() RETURN *"], ["query", "MATCH chain=(p1:Pokemon)-[:EVOLVES_TO*2]->(p3:Pokemon) WHERE NOT (p3)-[:EVOLVES_TO]->() RETURN *"], ["button", "sinnohMap"], ["query", "MATCH (n) WHERE n:City or n:Town or n:Lake RETURN n"], ["query", "MATCH p=(start:City{name:'Snowpoint City'})-[:ROUTE*]-(end:City{name:'Hearthome City'}) RETURN p"], ["query", "MATCH p=(start:City{name:'Snowpoint City'})-[:ROUTE*]-(end:City{name:'Hearthome City'}) RETURN length(p)"], ["query", "MATCH p=(start:City{name:'Snowpoint City'})-[:ROUTE*]-(end:City{name:'Hearthome City'}) RETURN length(p), p"], ["query", "MATCH p=shortestPath((start:City{name:'Snowpoint City'})-[:ROUTE*..10]-(end:City{name:'Hearthome City'})) RETURN length(p), p"], ["href", "https://github.com/veekun/pokedex"], ["href", "https://github.com/jquery/jquery"], ["href", "https://github.com/highlightjs/highlight.js"]], template: function AppComponent_Template(rf, ctx) { if (rf & 1) { +AppComponent.ɵcmp = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({ type: AppComponent, selectors: [["app-root"]], decls: 282, vars: 0, consts: [["color", "primary"], [1, "content"], [1, "lecture-part"], ["query", "()", "copy", "false"], ["query", "[]", "copy", "false"], ["query", "-- -> <-", "copy", "false"], ["query", ":Label1 :Label1:Label2 :LABEL_FOR_AN_EDGE"], ["href", "https://neo4j.com/docs/cypher-manual/current/", "target", "_blank"], ["query", "CREATE ()"], ["query", "CREATE (n:Student{name: 'Alex'}) RETURN n"], ["query", "MATCH (n:Student{name: 'Alex'}) RETURN n"], ["query", "MATCH (n:Student{name: 'Alex'}) SET n.study = 'computer science' RETURN n"], ["query", "MATCH (n) RETURN n"], ["query", "MATCH (n) WHERE NOT n:Student RETURN n"], ["query", "MATCH (n) WHERE size(labels(n)) = 0 RETURN n"], ["query", "MATCH (n) WHERE size(labels(n)) = 0 DELETE n"], ["query", "CREATE (l:Lecture{topic: 'GraphDBs'}) WITH l MATCH (s:Student{name: 'Alex'}) WITH l, s CREATE (s)-[:LISTENS]->(l) RETURN *"], ["query", "MATCH (s:Student{name: 'Alex'}) DELETE s", "copy", "false"], ["query", "MATCH (s:Student{name: 'Alex'}) DETACH DELETE s"], ["query", "MERGE (s:Student{name: 'Kim'}) WITH s MERGE (l:Lecture{topic: 'GraphDBs'}) WITH s, l MERGE (s)-[:LISTENS]->(l) RETURN *"], ["query", "MERGE (s:Student{name: 'Kim'})-[:LISTENS]->(l:Lecture{topic: 'GraphDBs'}) RETURN *"], ["query", "MATCH (l:Lecture{topic: 'GraphDBs'}) REMOVE l.topic RETURN l"], ["query", "MATCH (n) DETACH DELETE n"], ["button", "clear"], ["button", "pokemon"], ["query", "MATCH (node) RETURN node LIMIT 25"], ["query", "MATCH (pokemon:Pokemon) RETURN pokemon LIMIT 25"], ["query", "MATCH (t:Type) RETURN t"], ["query", "MATCH (p:Pokemon), (t:Type) RETURN p, t LIMIT 25"], ["query", "MATCH (p:Pokemon)-[:HAS_TYPE]-(t:Type) RETURN p, t LIMIT 25"], ["query", "MATCH (p:Pokemon)-[:HAS_TYPE]-(t:Type) RETURN * LIMIT 25"], ["query", "MATCH (p:Legendary) RETURN p"], ["query", "MATCH (p:Pokemon:Legendary) RETURN p"], ["query", "MATCH (p:Legendary:Pokemon) RETURN p"], ["query", "MATCH (p:Pokemon) WHERE p.name = 'pikachu' RETURN p"], ["query", "MATCH (p:Pokemon{name: 'pikachu'}) RETURN *"], ["copy", "false", "query", "MATCH (n) WHERE id(n) = 42 RETURN n"], ["query", "MATCH (n:Pokemon) WHERE n.name STARTS WITH 'pi' RETURN n"], ["query", "MATCH (n:Pokemon) WHERE n.name STARTS WITH 'pi' or n.name = 'charizard' RETURN n"], ["query", "MATCH (n:Pokemon) WHERE n.name STARTS WITH 'c' and n.pokedexId <= 150 RETURN n"], ["query", "MATCH (p:Pokemon)-[:HAS_TYPE]-(:Type{name: 'fire'}) WHERE p.pokedexId <= 150 RETURN *"], ["query", "MATCH (p:Pokemon)-[:HAS_TYPE{slot: 2}]-(t:Type) WHERE t.name = 'fire' RETURN *"], ["query", "MATCH (p:Pokemon) WHERE NOT (p)-[:EVOLVES_TO]->() RETURN p LIMIT 25"], ["query", "MATCH chain=(p1:Pokemon)-[:EVOLVES_TO]->(p2:Pokemon) WHERE NOT (p2)-[:EVOLVES_TO]->() RETURN chain"], ["query", "MATCH (p1:Pokemon)-[:EVOLVES_TO*2]->(p3:Pokemon) WHERE NOT (p3)-[:EVOLVES_TO]->() RETURN *"], ["query", "MATCH chain=(p1:Pokemon)-[:EVOLVES_TO*2]->(p3:Pokemon) WHERE NOT (p3)-[:EVOLVES_TO]->() RETURN *"], ["button", "sinnohMap"], ["query", "MATCH (n) WHERE n:City or n:Town or n:Lake RETURN n"], ["query", "MATCH p=(start:City{name:'Snowpoint City'})-[:ROUTE*]-(end:City{name:'Hearthome City'}) RETURN p"], ["query", "MATCH p=(start:City{name:'Snowpoint City'})-[:ROUTE*]-(end:City{name:'Hearthome City'}) RETURN length(p)"], ["query", "MATCH p=(start:City{name:'Snowpoint City'})-[:ROUTE*]-(end:City{name:'Hearthome City'}) RETURN length(p), p"], ["query", "MATCH p=shortestPath((start:City{name:'Snowpoint City'})-[:ROUTE*..10]-(end:City{name:'Hearthome City'})) RETURN length(p), p"], ["href", "https://github.com/veekun/pokedex"], ["href", "https://github.com/jquery/jquery"], ["href", "https://github.com/highlightjs/highlight.js"]], template: function AppComponent_Template(rf, ctx) { if (rf & 1) { _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "mat-toolbar", 0); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1, "Neo4J Demo Control Panel"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); @@ -404,228 +408,333 @@ AppComponent.ɵcmp = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineCompo _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](27, "https://neo4j.com/docs/cypher-manual/current/"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](28, "h2"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](29, "Simple MATCH queries"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](29, "Creating our First Entries"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](30, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](31, " For this part, you should load the Pokemon example data. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](32, "app-database-control", 8); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](31, " We will start by creating our first node "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](32, "app-snippset", 8); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](33, " This only inserts an empty node into the database without a label or any content. "); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](33, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](34, " We will start by simply fetching all nodes in the database. Because there might be a lot of them, we limit the number of results. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](35, "app-snippset", 9); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](36, " The "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](37, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](38, "MATCH"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](34, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](35, " So next, we create a node with the label "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](36, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](37, "Student"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](39, " keyword tells the database we want to fetch some data according to a certain pattern which is/are given afterwards. All elements matching parts of the pattern are stored in a variable if one is given, in our case it is called "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](40, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](41, "node"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](38, " and a name. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](39, "app-snippset", 9); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](40, " This time, the node is stored in the variable "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](41, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](42, "n"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](42, ". The last part of the query is the "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](43, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](44, "RETURN"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](43, ", so we can "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](44, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](45, "RETURN"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](45, " after which all variables we want in our result are specified, in our case only "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](46, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](47, "node"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](46, " it at the end of the query. "); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](48, ". The optional "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](47, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](48, " We now also want to add a property "); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](49, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](50, "LIMIT"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](51, " caps the results after the given number. Without this, our database would return us 916 elements for the Pokemon test dataset. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](50, "study"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](52, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](53, " If we only want a specific type of nodes, we can specify this by adding a label to the pattern. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](54, "app-snippset", 10); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](51, " to our student. What we need is to first get the node out of the database again using "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](52, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](53, "MATCH"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](55, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](56, " To show the difference, we now query the types Pokemon can have. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](54, " like this: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](55, "app-snippset", 10); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](56, " If this query returns our previously created node, we can enhance the query. "); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](57, "app-snippset", 11); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](58, " Because there are only 18, we can omit the "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](59, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](60, "LIMIT"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](61, ". "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](62, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](63, " In this example we combine the previous two queries by specifying two patterns. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](64, "app-snippset", 12); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](65, " We now limit the number of results again to 25. This query is a very bad example (and Neo4J Browser warns about this one), because we are actually building the Cartesian product of the two sets of results. According to Neo4J Browser, the number of records would be 16164. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](66, "br"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](67, " A better query is to ask for a Pokemon and its adjacent type: "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](68, "app-snippset", 13); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](69, " Here, the label "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](58, " This gets the node out of the database, modifies it by adding the property study and then returns the modified version back to us. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](59, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](60, " We still have the empty node in the database which we do not need any longer, so we want to remove it. First, we have to make sure, we get match only the node we want to delete: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](61, "app-snippset", 12); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](62, " This has the problem that we also get our students, so we need to filter them out: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](63, "app-snippset", 13); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](64, " We could also do this one for the case we have multiple labels in the database: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](65, "app-snippset", 14); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](66, " For the actual deletion, we replace the "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](67, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](68, "RETURN"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](69, " part with "); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](70, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](71, "HAS_TYPE"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](71, "DELETE"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](72, " is the label of an edge connecting a Pokemon with its type. And because we both of the variables returned, we can replace "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](73, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](74, "p, t"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](72, ": "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](73, "app-snippset", 15); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](75, " with an asterisk. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](76, "app-snippset", 14); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](74, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](75, " To add some edges, we need more nodes, so we create a lecture, find our student and attach both with an edge. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](76, "app-snippset", 16); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](77, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](78, " Nodes and edges can also have multiple labels. For example there are normal Pokemon and legendary ones (which are unique). The latter ones have two labels and can be queried accordingly. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](79, "app-snippset", 15); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](80, "app-snippset", 16); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](81, "app-snippset", 17); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](82, " All three queries yield the same result. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](83, "h2"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](84, "Filtering with Properties"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](85, " So far, we only selected nodes based on the labels. Most of the time, we also want to filter based on the stored properties. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](86, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](87, " We now want to find the most famous Pokemon. Please be aware that the string comparison is case sensitive and the name is given in lower case. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](88, "app-snippset", 18); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](89, " The filtering is like in SQL done with the "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](90, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](91, "WHERE"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](92, " part. Here, we access the property "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](93, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](94, "name"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](95, " and compare it against "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](96, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](97, "'pikachu'"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](98, ". Another possibilily is to include the name already in the pattern: "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](99, "app-snippset", 19); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](100, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](101, " We can also filter for an internal id "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](102, "app-snippset", 20); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](103, " Please note that the id is not really predictable and this query might not yield a meaningful result. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](104, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](105, " We can also filter using all kinds of functions and combinations. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](106, "app-snippset", 21); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](107, "app-snippset", 22); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](108, "app-snippset", 23); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](109, "h2"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](110, "Filtering with Paths"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](111, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](112, " We can also use the paths to enhance our filtering. For example, we want only fire Pokemon from the first generation (which means a pokedexId <= 150). "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](113, "app-snippset", 24); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](114, " Because we did not assign a variable to "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](115, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](116, ":Type"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](117, ", we could use "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](118, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](119, "RETURN *"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](120, " and only got the Pokemon. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](78, " After Alex graduated, the nodes is eventually removed, so we try this query: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](79, "app-snippset", 17); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](80, " Which won't execute because as Neo4J says "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](81, "em"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](82, "Cannot delete node<0>, because it still has relationships. To delete this node, you must first delete its relationships."); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](121, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](122, " Also edges can have properties. Pokemon might have more than one type. We now query all Pokemon with fire as secondary type. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](123, "app-snippset", 25); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](83, " Instead, we exlicilty need to state that we want also the relationships removed by "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](84, "app-snippset", 18); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](124, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](125, " We can also check for the absence of a certain path. In the next example, we want all pokemon which cannot evolve further. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](126, "app-snippset", 26); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](127, " The "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](128, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](129, "()"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](85, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](86, " Sometimes, we want a node, but are not sure, whether it is already existing. For this case, we can use "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](87, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](88, "MERGE"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](130, " here stands for an arbitrary node we do not restrict in any way and also do not store in a variable. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](131, "br"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](132, " Please note that we used "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](133, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](134, "-[]->"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](135, " which is a directed edge instead of the "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](136, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](137, "-[]-"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](138, " we used earlier. All edges in Neo4J are directed and we can care about the direction or not. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](139, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](140, " Path patterns can be arbitrary complex. To find all pokemon having only two evolution states, we can use this query: "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](141, "app-snippset", 27); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](142, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](143, " For Pokemon with three evolutionary levels, we can use an abbreviation: "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](144, "app-snippset", 28); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](145, " Where we do not see the full path but only start end end. If we again store the paths in a variable, we get all three Pokemon. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](146, "app-snippset", 29); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](147, "h2"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](148, "Path finding"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](149, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](150, " For this part, you should load the Sinnoh example map. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](151, "app-database-control", 30); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](152, " Please note I did some simplifications to the map. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](89, " which tries to lookup a node and nothing is found, creates it as if "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](90, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](91, "CREATE"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](153, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](154, " First of all, let's have a look at the whole map. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](155, "app-snippset", 31); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](156, " Another way of querying with labels. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](92, " was used. For example, to add another student to our (existing) lecture: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](93, "app-snippset", 19); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](94, " ATTENTION: If we used "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](95, "app-snippset", 20); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](96, " We would have got another lecture about graph databases because Neo4J would be looking for a lecture with an incoming "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](97, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](98, "LISTENS"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](157, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](158, " We can now find paths from "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](159, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](160, "Snowpoint City"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](99, " edge attaching a student named Kim. Actually if you use the second query, change the name and execute it, you would end up with another new lecture with only one student. "); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](161, " to "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](162, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](163, "Hearthome City"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](100, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](101, " To remove a property of a node, "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](102, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](103, "REMOVE"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](104, " is used and not DELETE. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](105, "app-snippset", 21); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](106, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](107, " At this point, we finished the basics of creating and deleting nodes and edges and now focus on fetching data. Before that, we can clean up the database, either by "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](108, "app-snippset", 22); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](109, " Matching, detaching and deleting everything in the database, or simply use the button below. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](110, "app-database-control", 23); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](111, "h2"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](112, "Simple MATCH queries"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](113, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](114, " For this part, you should load the Pokemon example data. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](115, "app-database-control", 24); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](116, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](117, " We will start by simply fetching all nodes in the database. Because there might be a lot of them, we limit the number of results. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](118, "app-snippset", 25); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](119, " The "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](120, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](121, "MATCH"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](122, " keyword tells the database we want to fetch some data according to a certain pattern which is/are given afterwards. All elements matching parts of the pattern are stored in a variable if one is given, in our case it is called "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](123, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](124, "node"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](125, ". The last part of the query is the "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](126, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](127, "RETURN"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](128, " after which all variables we want in our result are specified, in our case only "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](129, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](130, "node"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](131, ". The optional "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](132, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](133, "LIMIT"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](134, " caps the results after the given number. Without this, our database would return us 916 elements for the Pokemon test dataset. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](135, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](136, " If we only want a specific type of nodes, we can specify this by adding a label to the pattern. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](137, "app-snippset", 26); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](138, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](139, " To show the difference, we now query the types Pokemon can have. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](140, "app-snippset", 27); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](141, " Because there are only 18, we can omit the "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](142, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](143, "LIMIT"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](144, ". "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](145, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](146, " In this example we combine the previous two queries by specifying two patterns. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](147, "app-snippset", 28); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](148, " We now limit the number of results again to 25. This query is a very bad example (and Neo4J Browser warns about this one), because we are actually building the Cartesian product of the two sets of results. According to Neo4J Browser, the number of records would be 16164. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](149, "br"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](150, " A better query is to ask for a Pokemon and its adjacent type: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](151, "app-snippset", 29); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](152, " Here, the label "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](153, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](154, "HAS_TYPE"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](155, " is the label of an edge connecting a Pokemon with its type. And because we both of the variables returned, we can replace "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](156, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](157, "p, t"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](158, " with an asterisk. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](159, "app-snippset", 30); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](160, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](161, " Nodes and edges can also have multiple labels. For example there are normal Pokemon and legendary ones (which are unique). The latter ones have two labels and can be queried accordingly. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](162, "app-snippset", 31); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](163, "app-snippset", 32); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](164, "app-snippset", 33); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](165, " All three queries yield the same result. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](166, "h2"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](167, "Filtering with Properties"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](168, " So far, we only selected nodes based on the labels. Most of the time, we also want to filter based on the stored properties. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](169, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](170, " We now want to find the most famous Pokemon. Please be aware that the string comparison is case sensitive and the name is given in lower case. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](171, "app-snippset", 34); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](172, " The filtering is like in SQL done with the "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](173, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](174, "WHERE"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](175, " part. Here, we access the property "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](176, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](177, "name"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](178, " and compare it against "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](179, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](180, "'pikachu'"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](181, ". Another possibilily is to include the name already in the pattern: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](182, "app-snippset", 35); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](183, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](184, " We can also filter for an internal id "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](185, "app-snippset", 36); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](186, " Please note that the id is not really predictable and this query might not yield a meaningful result. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](187, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](188, " We can also filter using all kinds of functions and combinations. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](189, "app-snippset", 37); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](190, "app-snippset", 38); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](191, "app-snippset", 39); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](192, "h2"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](193, "Filtering with Paths"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](194, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](195, " We can also use the paths to enhance our filtering. For example, we want only fire Pokemon from the first generation (which means a pokedexId <= 150). "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](196, "app-snippset", 40); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](197, " Because we did not assign a variable to "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](198, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](199, ":Type"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](200, ", we could use "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](201, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](202, "RETURN *"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](203, " and only got the Pokemon. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](204, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](205, " Also edges can have properties. Pokemon might have more than one type. We now query all Pokemon with fire as secondary type. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](206, "app-snippset", 41); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](207, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](208, " We can also check for the absence of a certain path. In the next example, we want all pokemon which cannot evolve further. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](209, "app-snippset", 42); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](210, " The "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](211, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](212, "()"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](213, " here stands for an arbitrary node we do not restrict in any way and also do not store in a variable. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](214, "br"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](215, " Please note that we used "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](216, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](217, "-[]->"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](218, " which is a directed edge instead of the "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](219, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](220, "-[]-"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](221, " we used earlier. All edges in Neo4J are directed and we can care about the direction or not. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](222, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](223, " Path patterns can be arbitrary complex. To find all pokemon having only two evolution states, we can use this query: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](224, "app-snippset", 43); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](225, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](226, " For Pokemon with three evolutionary levels, we can use an abbreviation: "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](227, "app-snippset", 44); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](228, " Where we do not see the full path but only start end end. If we again store the paths in a variable, we get all three Pokemon. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](229, "app-snippset", 45); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](230, "h2"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](231, "Path finding"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](232, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](233, " For this part, you should load the Sinnoh example map. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](234, "app-database-control", 46); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](235, " Please note I did some simplifications to the map. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](236, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](237, " First of all, let's have a look at the whole map. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](238, "app-snippset", 47); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](239, " Another way of querying with labels. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](240, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](241, " We can now find paths from "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](242, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](243, "Snowpoint City"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](164, ". "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](165, "app-snippset", 32); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](166, " And get the lengths of each route. "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](167, "app-snippset", 33); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](168, " And also both "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](169, "app-snippset", 34); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](244, " to "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](245, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](246, "Hearthome City"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](247, ". "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](248, "app-snippset", 48); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](249, " And get the lengths of each route. "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](250, "app-snippset", 49); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](251, " And also both "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](252, "app-snippset", 50); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](170, "div", 2); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](171, " Neo4J also offers some interesting functions like "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](172, "b"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](173, "shortestPath()"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](253, "div", 2); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](254, " Neo4J also offers some interesting functions like "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](255, "b"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](256, "shortestPath()"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](174, " which finds the shortest instance of an path in an (according to the documentation) efficient way. Neo4J Browser advices to use an upper limit here to avoid long execution times "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](175, "app-snippset", 35); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](257, " which finds the shortest instance of an path in an (according to the documentation) efficient way. Neo4J Browser advices to use an upper limit here to avoid long execution times "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](258, "app-snippset", 51); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](176, "mat-expansion-panel"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](177, "mat-expansion-panel-header"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](178, "mat-panel-title"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](179, " Sources "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](259, "mat-expansion-panel"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](260, "mat-expansion-panel-header"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](261, "mat-panel-title"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](262, " Sources "); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](180, "h3"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](181, "Pokemon data"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](263, "h3"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](264, "Pokemon data"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](182, " Many thanks to GitHub user Eevee/Veekun for providing a lot of data about Pokemon in CSV data under MIT License "); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](183, "a", 36); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](184, "https://github.com/veekun/pokedex"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](265, " Many thanks to GitHub user Eevee/Veekun for providing a lot of data about Pokemon in CSV data under MIT License "); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](266, "a", 52); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](267, "https://github.com/veekun/pokedex"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](185, "pre"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](186, "Copyright \u00A9 2009 Alex Munroe (Eevee)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](268, "pre"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](269, "Copyright \u00A9 2009 Alex Munroe (Eevee)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](187, "h3"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](188, "jQuery"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](270, "h3"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](271, "jQuery"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](189, "a", 37); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](190, "https://github.com/jquery/jquery"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](272, "a", 53); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](273, "https://github.com/jquery/jquery"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](191, "pre"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](192, "Copyright OpenJS Foundation and other contributors, https://openjsf.org/\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](274, "pre"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](275, "Copyright OpenJS Foundation and other contributors, https://openjsf.org/\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](193, "h3"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](194, "highlight.js"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](276, "h3"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](277, "highlight.js"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](195, "a", 38); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](196, "https://github.com/highlightjs/highlight.js"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](278, "a", 54); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](279, "https://github.com/highlightjs/highlight.js"); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](197, "pre"); - _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](198, "BSD 3-Clause License\n\nCopyright (c) 2006, Ivan Sagalaev.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](280, "pre"); + _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](281, "BSD 3-Clause License\n\nCopyright (c) 2006, Ivan Sagalaev.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"](); } }, directives: [_angular_material_toolbar__WEBPACK_IMPORTED_MODULE_1__["MatToolbar"], _components_browser_browser_component__WEBPACK_IMPORTED_MODULE_2__["BrowserComponent"], _angular_material_divider__WEBPACK_IMPORTED_MODULE_3__["MatDivider"], _components_database_control_database_control_component__WEBPACK_IMPORTED_MODULE_4__["DatabaseControlComponent"], _components_snippset_snippet_component__WEBPACK_IMPORTED_MODULE_5__["SnippetComponent"], _angular_material_expansion__WEBPACK_IMPORTED_MODULE_6__["MatExpansionPanel"], _angular_material_expansion__WEBPACK_IMPORTED_MODULE_6__["MatExpansionPanelHeader"], _angular_material_expansion__WEBPACK_IMPORTED_MODULE_6__["MatExpansionPanelTitle"]], styles: [".content[_ngcontent-%COMP%] {\n margin: auto;\n max-width: 1200px;\n padding-bottom: 100px;\n}\n\nmat-divider[_ngcontent-%COMP%] {\n margin-top: 10px;\n margin-bottom: 15px;\n}\n\n.lecture-part[_ngcontent-%COMP%] {\n margin-bottom: 30px;\n}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwcC5jb21wb25lbnQuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0VBQ0UsWUFBWTtFQUNaLGlCQUFpQjtFQUNqQixxQkFBcUI7QUFDdkI7O0FBRUE7RUFDRSxnQkFBZ0I7RUFDaEIsbUJBQW1CO0FBQ3JCOztBQUVBO0VBQ0UsbUJBQW1CO0FBQ3JCIiwiZmlsZSI6ImFwcC5jb21wb25lbnQuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLmNvbnRlbnQge1xuICBtYXJnaW46IGF1dG87XG4gIG1heC13aWR0aDogMTIwMHB4O1xuICBwYWRkaW5nLWJvdHRvbTogMTAwcHg7XG59XG5cbm1hdC1kaXZpZGVyIHtcbiAgbWFyZ2luLXRvcDogMTBweDtcbiAgbWFyZ2luLWJvdHRvbTogMTVweDtcbn1cblxuLmxlY3R1cmUtcGFydCB7XG4gIG1hcmdpbi1ib3R0b206IDMwcHg7XG59XG4iXX0= */"] }); diff --git a/src/main/resources/static/main.js.map b/src/main/resources/static/main.js.map index 0be6cc6..687cec8 100644 --- a/src/main/resources/static/main.js.map +++ b/src/main/resources/static/main.js.map @@ -1 +1 @@ -{"version":3,"sources":["./src/app/components/browser/browser.component.ts","./src/app/components/browser/browser.component.html","./src/environments/environment.ts","./src/app/components/database-control/database-control.component.html","./src/app/components/database-control/database-control.component.ts","./src/app/components/snippset/snippet.component.html","./src/app/components/snippset/snippet.component.ts","./src/app/app.component.ts","./src/app/app.component.html","./src/app/app.module.ts","./src/app/services/database.service.ts","./src/main.ts","./$_lazy_route_resource lazy namespace object"],"names":[],"mappings":"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","file":"main.js","sourcesContent":["import { Component, OnInit } from '@angular/core';\n\n@Component({\n selector: 'app-browser',\n templateUrl: './browser.component.html',\n styleUrls: ['./browser.component.css']\n})\nexport class BrowserComponent implements OnInit {\n\n constructor() { }\n\n ngOnInit(): void {\n }\n\n}\n","

Neo4J Browser

\n
\n http://localhost:8080/browser/index.html\n
\n
Connect URL
\n
bolt://localhost
\n\n
Authentication type
\n
Username / Password
\n\n
Username
\n
<empty>
\n\n
Password
\n
<empty>
\n
\n Basically, just click \n
\n","// This file can be replaced during build by using the `fileReplacements` array.\n// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.\n// The list of file replacements can be found in `angular.json`.\n\nexport const environment = {\n production: false\n};\n\n/*\n * For easier debugging in development mode, you can import the following file\n * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.\n *\n * This import should be commented out in production mode because it will have a negative impact\n * on performance if an error is thrown.\n */\n// import 'zone.js/dist/zone-error'; // Included with Angular CLI.\n","

Database Control

\n\n
\n \n {{clearDatabaseMessage}}\n
\n
\n \n {{loadPokemonMessage}}\n
\n
\n \n {{loadSinnohMapMessage}}\n
\n\n\n\n","import {Component, Input, OnInit} from '@angular/core';\nimport {DatabaseService} from '../../services/database.service';\n\n@Component({\n selector: 'app-database-control',\n templateUrl: './database-control.component.html',\n styleUrls: ['./database-control.component.css']\n})\nexport class DatabaseControlComponent implements OnInit {\n clearDatabaseMessage: string = null;\n loadPokemonMessage: string = null;\n loadSinnohMapMessage: string = null;\n transactionInProgress = false;\n\n @Input()\n button: string = null;\n\n constructor(private databaseService: DatabaseService) {\n }\n\n ngOnInit(): void {\n }\n\n loadPokemon(): void {\n this.transactionInProgress = true;\n this.loadPokemonMessage = 'Running...';\n this.databaseService.loadPokemon().subscribe(res => {\n this.loadPokemonMessage = res.result;\n this.transactionInProgress = false;\n },\n error => {\n this.loadPokemonMessage = null;\n this.transactionInProgress = false;\n console.error(error);\n alert('An error occured, see the console.');\n });\n }\n\n loadSinnohMap(): void {\n this.transactionInProgress = true;\n this.loadSinnohMapMessage = 'Running...';\n this.databaseService.loadSinnohMap().subscribe(res => {\n this.loadSinnohMapMessage = res.result;\n this.transactionInProgress = false;\n },\n error => {\n this.loadSinnohMapMessage = null;\n this.transactionInProgress = false;\n console.error(error);\n alert('An error occured, see the console.');\n });\n }\n\n clearDatabase(): void {\n this.transactionInProgress = true;\n this.clearDatabaseMessage = 'Running...';\n this.loadPokemonMessage = null;\n this.loadSinnohMapMessage = null;\n this.databaseService.clearDatabase().subscribe(res => {\n this.clearDatabaseMessage = res.result;\n this.transactionInProgress = false;\n },\n error => {\n this.clearDatabaseMessage = null;\n this.transactionInProgress = false;\n console.error(error);\n alert('An error occured, see the console.');\n });\n }\n\n}\n","
\n
public static int main();
\n \n
\n","import {Component, ElementRef, Input, OnInit, Renderer2} from '@angular/core';\n\n\n@Component({\n selector: 'app-snippset',\n templateUrl: './snippet.component.html',\n styleUrls: ['./snippet.component.css']\n})\nexport class SnippetComponent implements OnInit {\n\n @Input()\n query: string;\n\n copy_ = true;\n\n constructor() {\n }\n\n ngOnInit(): void {\n }\n\n @Input()\n set copy(value: string) {\n if (value === 'false') {\n this.copy_ = false;\n } else {\n this.copy_ = true;\n }\n }\n\n}\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'app-root',\n templateUrl: './app.component.html',\n styleUrls: ['./app.component.css']\n})\nexport class AppComponent {\n title = 'frontend';\n}\n","Neo4J Demo Control Panel\n\n
\n \n \n \n\n \n

Basic building blocks

\n\n
\n Two parenthesis denote a node in cypher\n \n
\n\n
\n Two brackets are used for referencing edges\n \n
\n\n\n
\n Nodes and edges are connected by dashes and less/greater signs\n <-\" copy=\"false\">\n
\n\n
\n Nodes and edges can have multiple labels which are each started by a colon.
\n The case is not mandatory but significant.\n \n
\n\n\n \n

Official Cypher Manual

\n https://neo4j.com/docs/cypher-manual/current/\n\n\n

Simple MATCH queries

\n\n
\n For this part, you should load the Pokemon example data.\n \n
\n\n
\n We will start by simply fetching all nodes in the database. Because there might be a lot of them, we limit the number of results.\n \n The MATCH keyword tells the database we want to fetch some data according to a certain pattern which is/are given afterwards.\n All elements matching parts of the pattern are stored in a variable if one is given, in our case it is called node.\n The last part of the query is the RETURN after which all variables we want in our result are specified, in our case only node.\n The optional LIMIT caps the results after the given number.\n Without this, our database would return us 916 elements for the Pokemon test dataset.\n
\n\n
\n If we only want a specific type of nodes, we can specify this by adding a label to the pattern.\n \n
\n\n
\n To show the difference, we now query the types Pokemon can have.\n \n Because there are only 18, we can omit the LIMIT.\n
\n\n
\n In this example we combine the previous two queries by specifying two patterns.\n \n We now limit the number of results again to 25.\n This query is a very bad example (and Neo4J Browser warns about this one), because we are actually building the Cartesian product of the two sets of results.\n According to Neo4J Browser, the number of records would be 16164.
\n A better query is to ask for a Pokemon and its adjacent type:\n \n Here, the label HAS_TYPE is the label of an edge connecting a Pokemon with its type.\n And because we both of the variables returned, we can replace p, t with an asterisk.\n \n
\n\n
\n Nodes and edges can also have multiple labels.\n For example there are normal Pokemon and legendary ones (which are unique).\n The latter ones have two labels and can be queried accordingly.\n \n \n \n All three queries yield the same result.\n
\n\n

Filtering with Properties

\n So far, we only selected nodes based on the labels. Most of the time, we also want to filter based on the stored properties.\n\n
\n We now want to find the most famous Pokemon.\n Please be aware that the string comparison is case sensitive and the name is given in lower case.\n \n The filtering is like in SQL done with the WHERE part.\n Here, we access the property name and compare it against 'pikachu'.\n Another possibilily is to include the name already in the pattern:\n \n
\n\n
\n We can also filter for an internal id\n \n Please note that the id is not really predictable and this query might not yield a meaningful result.\n
\n\n
\n We can also filter using all kinds of functions and combinations.\n \n \n \n
\n\n

Filtering with Paths

\n\n
\n We can also use the paths to enhance our filtering.\n For example, we want only fire Pokemon from the first generation (which means a pokedexId <= 150).\n \n Because we did not assign a variable to :Type, we could use RETURN * and only got the Pokemon.\n
\n\n
\n Also edges can have properties.\n Pokemon might have more than one type.\n We now query all Pokemon with fire as secondary type.\n \n
\n\n
\n We can also check for the absence of a certain path.\n In the next example, we want all pokemon which cannot evolve further.\n () RETURN p LIMIT 25\">\n The () here stands for an arbitrary node we do not restrict in any way and also do not store in a variable.
\n Please note that we used -[]-> which is a directed edge instead of the -[]- we used earlier.\n All edges in Neo4J are directed and we can care about the direction or not.\n
\n\n
\n Path patterns can be arbitrary complex.\n To find all pokemon having only two evolution states, we can use this query:\n (p2:Pokemon) WHERE NOT (p2)-[:EVOLVES_TO]->() RETURN chain\">\n
\n\n
\n For Pokemon with three evolutionary levels, we can use an abbreviation:\n (p3:Pokemon) WHERE NOT (p3)-[:EVOLVES_TO]->() RETURN *\">\n Where we do not see the full path but only start end end.\n If we again store the paths in a variable, we get all three Pokemon.\n (p3:Pokemon) WHERE NOT (p3)-[:EVOLVES_TO]->() RETURN *\">\n
\n\n

Path finding

\n
\n For this part, you should load the Sinnoh example map.\n \n Please note I did some simplifications to the map.\n
\n\n
\n First of all, let's have a look at the whole map.\n \n Another way of querying with labels.\n
\n\n
\n We can now find paths from Snowpoint City to Hearthome City.\n \n And get the lengths of each route.\n \n And also both\n \n
\n\n
\n Neo4J also offers some interesting functions like shortestPath() which finds the shortest instance of an path in an (according to the documentation) efficient way.\n Neo4J Browser advices to use an upper limit here to avoid long execution times\n \n
\n\n\n\n
\n\n\n \n \n Sources\n \n \n

Pokemon data

\n Many thanks to GitHub user Eevee/Veekun for providing a lot of data about Pokemon in CSV data under MIT License\n https://github.com/veekun/pokedex\n\n
Copyright © 2009 Alex Munroe (Eevee)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.
\n\n

jQuery

\n https://github.com/jquery/jquery\n
Copyright OpenJS Foundation and other contributors, https://openjsf.org/\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\n\n

highlight.js

\n https://github.com/highlightjs/highlight.js\n
BSD 3-Clause License\n\nCopyright (c) 2006, Ivan Sagalaev.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\n
\n","import { NgModule } from '@angular/core';\nimport { BrowserModule } from '@angular/platform-browser';\n\nimport { AppComponent } from './app.component';\nimport {MatToolbarModule} from '@angular/material/toolbar';\nimport {MatExpansionModule} from '@angular/material/expansion';\nimport {BrowserAnimationsModule} from '@angular/platform-browser/animations';\nimport {MatDividerModule} from '@angular/material/divider';\nimport { BrowserComponent } from './components/browser/browser.component';\nimport { DatabaseControlComponent } from './components/database-control/database-control.component';\nimport {MatButtonModule} from '@angular/material/button';\nimport {HttpClientModule} from '@angular/common/http';\nimport { SnippetComponent } from './components/snippset/snippet.component';\nimport {HIGHLIGHT_OPTIONS, HighlightModule} from 'ngx-highlightjs';\nimport {ClipboardModule} from '@angular/cdk/clipboard';\n\n@NgModule({\n declarations: [\n AppComponent,\n BrowserComponent,\n DatabaseControlComponent,\n SnippetComponent\n ],\n imports: [\n BrowserModule,\n MatToolbarModule,\n MatExpansionModule,\n BrowserAnimationsModule,\n MatDividerModule,\n MatButtonModule,\n HttpClientModule,\n HighlightModule,\n ClipboardModule\n ],\n providers: [{\n provide: HIGHLIGHT_OPTIONS,\n useValue: {\n coreLibraryLoader: () => import('highlight.js/lib/core'),\n languages: {\n cypher: () => import('../assets/cypher.js'),\n }\n }\n }],\n bootstrap: [AppComponent]\n})\nexport class AppModule { }\n","import {Injectable} from '@angular/core';\nimport {HttpClient} from '@angular/common/http';\nimport {Observable} from 'rxjs';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class DatabaseService {\n\n constructor(private http: HttpClient) {\n }\n\n public loadPokemon(): Observable {\n return this.http.post('http://localhost:8080/api/pokemon/load', null);\n }\n\n public loadSinnohMap(): Observable {\n return this.http.post('http://localhost:8080/api/sinnoh-map/load', null);\n }\n\n public clearDatabase(): Observable {\n return this.http.delete('http://localhost:8080/api/database');\n }\n}\n","import { enableProdMode } from '@angular/core';\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\n\nimport { AppModule } from './app/app.module';\nimport { environment } from './environments/environment';\n\nif (environment.production) {\n enableProdMode();\n}\n\nplatformBrowserDynamic().bootstrapModule(AppModule)\n .catch(err => console.error(err));\n","function webpackEmptyAsyncContext(req) {\n\t// Here Promise.resolve().then() is used instead of new Promise() to prevent\n\t// uncaught exception popping up in devtools\n\treturn Promise.resolve().then(function() {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t});\n}\nwebpackEmptyAsyncContext.keys = function() { return []; };\nwebpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;\nmodule.exports = webpackEmptyAsyncContext;\nwebpackEmptyAsyncContext.id = \"zn8P\";"],"sourceRoot":"webpack:///"} \ No newline at end of file +{"version":3,"sources":["./src/app/components/browser/browser.component.ts","./src/app/components/browser/browser.component.html","./src/environments/environment.ts","./src/app/components/database-control/database-control.component.html","./src/app/components/database-control/database-control.component.ts","./src/app/components/snippset/snippet.component.html","./src/app/components/snippset/snippet.component.ts","./src/app/app.component.ts","./src/app/app.component.html","./src/app/app.module.ts","./src/app/services/database.service.ts","./src/main.ts","./$_lazy_route_resource lazy namespace object"],"names":[],"mappings":"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","file":"main.js","sourcesContent":["import { Component, OnInit } from '@angular/core';\n\n@Component({\n selector: 'app-browser',\n templateUrl: './browser.component.html',\n styleUrls: ['./browser.component.css']\n})\nexport class BrowserComponent implements OnInit {\n\n constructor() { }\n\n ngOnInit(): void {\n }\n\n}\n","

Neo4J Browser

\n
\n http://localhost:8080/browser/index.html\n
\n
Connect URL
\n
bolt://localhost
\n\n
Authentication type
\n
Username / Password
\n\n
Username
\n
<empty>
\n\n
Password
\n
<empty>
\n
\n Basically, just enter localhost in the URL and click \n
\n","// This file can be replaced during build by using the `fileReplacements` array.\n// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.\n// The list of file replacements can be found in `angular.json`.\n\nexport const environment = {\n production: false\n};\n\n/*\n * For easier debugging in development mode, you can import the following file\n * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.\n *\n * This import should be commented out in production mode because it will have a negative impact\n * on performance if an error is thrown.\n */\n// import 'zone.js/dist/zone-error'; // Included with Angular CLI.\n","

Database Control

\n\n
\n \n {{clearDatabaseMessage}}\n
\n
\n \n {{loadPokemonMessage}}\n
\n
\n \n {{loadSinnohMapMessage}}\n
\n\n\n\n","import {Component, Input, OnInit} from '@angular/core';\nimport {DatabaseService} from '../../services/database.service';\n\n@Component({\n selector: 'app-database-control',\n templateUrl: './database-control.component.html',\n styleUrls: ['./database-control.component.css']\n})\nexport class DatabaseControlComponent implements OnInit {\n clearDatabaseMessage: string = null;\n loadPokemonMessage: string = null;\n loadSinnohMapMessage: string = null;\n transactionInProgress = false;\n\n @Input()\n button: string = null;\n\n constructor(private databaseService: DatabaseService) {\n }\n\n ngOnInit(): void {\n }\n\n loadPokemon(): void {\n this.transactionInProgress = true;\n this.loadPokemonMessage = 'Running...';\n this.databaseService.loadPokemon().subscribe(res => {\n this.loadPokemonMessage = res.result;\n this.transactionInProgress = false;\n },\n error => {\n this.loadPokemonMessage = null;\n this.transactionInProgress = false;\n console.error(error);\n alert('An error occured, see the console.');\n });\n }\n\n loadSinnohMap(): void {\n this.transactionInProgress = true;\n this.loadSinnohMapMessage = 'Running...';\n this.databaseService.loadSinnohMap().subscribe(res => {\n this.loadSinnohMapMessage = res.result;\n this.transactionInProgress = false;\n },\n error => {\n this.loadSinnohMapMessage = null;\n this.transactionInProgress = false;\n console.error(error);\n alert('An error occured, see the console.');\n });\n }\n\n clearDatabase(): void {\n this.transactionInProgress = true;\n this.clearDatabaseMessage = 'Running...';\n this.loadPokemonMessage = null;\n this.loadSinnohMapMessage = null;\n this.databaseService.clearDatabase().subscribe(res => {\n this.clearDatabaseMessage = res.result;\n this.transactionInProgress = false;\n },\n error => {\n this.clearDatabaseMessage = null;\n this.transactionInProgress = false;\n console.error(error);\n alert('An error occured, see the console.');\n });\n }\n\n}\n","
\n
public static int main();
\n \n
\n","import {Component, ElementRef, Input, OnInit, Renderer2} from '@angular/core';\n\n\n@Component({\n selector: 'app-snippset',\n templateUrl: './snippet.component.html',\n styleUrls: ['./snippet.component.css']\n})\nexport class SnippetComponent implements OnInit {\n\n @Input()\n query: string;\n\n copy_ = true;\n\n constructor() {\n }\n\n ngOnInit(): void {\n }\n\n @Input()\n set copy(value: string) {\n if (value === 'false') {\n this.copy_ = false;\n } else {\n this.copy_ = true;\n }\n }\n\n}\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'app-root',\n templateUrl: './app.component.html',\n styleUrls: ['./app.component.css']\n})\nexport class AppComponent {\n title = 'frontend';\n}\n","Neo4J Demo Control Panel\n\n
\n \n \n \n\n \n

Basic building blocks

\n\n
\n Two parenthesis denote a node in cypher\n \n
\n\n
\n Two brackets are used for referencing edges\n \n
\n\n\n
\n Nodes and edges are connected by dashes and less/greater signs\n <-\" copy=\"false\">\n
\n\n
\n Nodes and edges can have multiple labels which are each started by a colon.
\n The case is not mandatory but significant.\n \n
\n\n\n \n

Official Cypher Manual

\n https://neo4j.com/docs/cypher-manual/current/\n\n

Creating our First Entries

\n\n
\n We will start by creating our first node\n \n This only inserts an empty node into the database without a label or any content.\n
\n\n
\n So next, we create a node with the label Student and a name.\n \n This time, the node is stored in the variable n, so we can RETURN it at the end of the query.\n
\n\n
\n We now also want to add a property study to our student.\n What we need is to first get the node out of the database again using MATCH like this:\n \n If this query returns our previously created node, we can enhance the query.\n \n This gets the node out of the database, modifies it by adding the property study and then returns the modified version back to us.\n
\n\n
\n We still have the empty node in the database which we do not need any longer, so we want to remove it.\n First, we have to make sure, we get match only the node we want to delete:\n \n This has the problem that we also get our students, so we need to filter them out:\n \n We could also do this one for the case we have multiple labels in the database:\n \n For the actual deletion, we replace the RETURN part with DELETE:\n \n
\n\n
\n To add some edges, we need more nodes, so we create a lecture, find our student and attach both with an edge.\n (l) RETURN *\">\n
\n\n
\n After Alex graduated, the nodes is eventually removed, so we try this query:\n \n Which won't execute because as Neo4J says Cannot delete node<0>, because it still has relationships. To delete this node, you must first delete its relationships.\n Instead, we exlicilty need to state that we want also the relationships removed by\n \n
\n\n
\n Sometimes, we want a node, but are not sure, whether it is already existing.\n For this case, we can use MERGE which tries to lookup a node and nothing is found, creates it as if CREATE was used.\n For example, to add another student to our (existing) lecture:\n (l) RETURN *\">\n ATTENTION: If we used\n (l:Lecture{topic: 'GraphDBs'}) RETURN *\">\n We would have got another lecture about graph databases because Neo4J would be looking for a lecture with an incoming LISTENS edge attaching a student named Kim.\n Actually if you use the second query, change the name and execute it, you would end up with another new lecture with only one student.\n
\n\n
\n To remove a property of a node, REMOVE is used and not DELETE.\n \n
\n\n
\n At this point, we finished the basics of creating and deleting nodes and edges and now focus on fetching data.\n Before that, we can clean up the database, either by\n \n Matching, detaching and deleting everything in the database, or simply use the button below.\n \n
\n\n

Simple MATCH queries

\n\n
\n For this part, you should load the Pokemon example data.\n \n
\n\n
\n We will start by simply fetching all nodes in the database. Because there might be a lot of them, we limit the number of results.\n \n The MATCH keyword tells the database we want to fetch some data according to a certain pattern which is/are given afterwards.\n All elements matching parts of the pattern are stored in a variable if one is given, in our case it is called node.\n The last part of the query is the RETURN after which all variables we want in our result are specified, in our case only node.\n The optional LIMIT caps the results after the given number.\n Without this, our database would return us 916 elements for the Pokemon test dataset.\n
\n\n
\n If we only want a specific type of nodes, we can specify this by adding a label to the pattern.\n \n
\n\n
\n To show the difference, we now query the types Pokemon can have.\n \n Because there are only 18, we can omit the LIMIT.\n
\n\n
\n In this example we combine the previous two queries by specifying two patterns.\n \n We now limit the number of results again to 25.\n This query is a very bad example (and Neo4J Browser warns about this one), because we are actually building the Cartesian product of the two sets of results.\n According to Neo4J Browser, the number of records would be 16164.
\n A better query is to ask for a Pokemon and its adjacent type:\n \n Here, the label HAS_TYPE is the label of an edge connecting a Pokemon with its type.\n And because we both of the variables returned, we can replace p, t with an asterisk.\n \n
\n\n
\n Nodes and edges can also have multiple labels.\n For example there are normal Pokemon and legendary ones (which are unique).\n The latter ones have two labels and can be queried accordingly.\n \n \n \n All three queries yield the same result.\n
\n\n

Filtering with Properties

\n So far, we only selected nodes based on the labels. Most of the time, we also want to filter based on the stored properties.\n\n
\n We now want to find the most famous Pokemon.\n Please be aware that the string comparison is case sensitive and the name is given in lower case.\n \n The filtering is like in SQL done with the WHERE part.\n Here, we access the property name and compare it against 'pikachu'.\n Another possibilily is to include the name already in the pattern:\n \n
\n\n
\n We can also filter for an internal id\n \n Please note that the id is not really predictable and this query might not yield a meaningful result.\n
\n\n
\n We can also filter using all kinds of functions and combinations.\n \n \n \n
\n\n

Filtering with Paths

\n\n
\n We can also use the paths to enhance our filtering.\n For example, we want only fire Pokemon from the first generation (which means a pokedexId <= 150).\n \n Because we did not assign a variable to :Type, we could use RETURN * and only got the Pokemon.\n
\n\n
\n Also edges can have properties.\n Pokemon might have more than one type.\n We now query all Pokemon with fire as secondary type.\n \n
\n\n
\n We can also check for the absence of a certain path.\n In the next example, we want all pokemon which cannot evolve further.\n () RETURN p LIMIT 25\">\n The () here stands for an arbitrary node we do not restrict in any way and also do not store in a variable.
\n Please note that we used -[]-> which is a directed edge instead of the -[]- we used earlier.\n All edges in Neo4J are directed and we can care about the direction or not.\n
\n\n
\n Path patterns can be arbitrary complex.\n To find all pokemon having only two evolution states, we can use this query:\n (p2:Pokemon) WHERE NOT (p2)-[:EVOLVES_TO]->() RETURN chain\">\n
\n\n
\n For Pokemon with three evolutionary levels, we can use an abbreviation:\n (p3:Pokemon) WHERE NOT (p3)-[:EVOLVES_TO]->() RETURN *\">\n Where we do not see the full path but only start end end.\n If we again store the paths in a variable, we get all three Pokemon.\n (p3:Pokemon) WHERE NOT (p3)-[:EVOLVES_TO]->() RETURN *\">\n
\n\n

Path finding

\n
\n For this part, you should load the Sinnoh example map.\n \n Please note I did some simplifications to the map.\n
\n\n
\n First of all, let's have a look at the whole map.\n \n Another way of querying with labels.\n
\n\n
\n We can now find paths from Snowpoint City to Hearthome City.\n \n And get the lengths of each route.\n \n And also both\n \n
\n\n
\n Neo4J also offers some interesting functions like shortestPath() which finds the shortest instance of an path in an (according to the documentation) efficient way.\n Neo4J Browser advices to use an upper limit here to avoid long execution times\n \n
\n\n\n\n
\n\n\n \n \n Sources\n \n \n

Pokemon data

\n Many thanks to GitHub user Eevee/Veekun for providing a lot of data about Pokemon in CSV data under MIT License\n https://github.com/veekun/pokedex\n\n
Copyright © 2009 Alex Munroe (Eevee)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.
\n\n

jQuery

\n https://github.com/jquery/jquery\n
Copyright OpenJS Foundation and other contributors, https://openjsf.org/\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\n\n

highlight.js

\n https://github.com/highlightjs/highlight.js\n
BSD 3-Clause License\n\nCopyright (c) 2006, Ivan Sagalaev.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\n
\n","import { NgModule } from '@angular/core';\nimport { BrowserModule } from '@angular/platform-browser';\n\nimport { AppComponent } from './app.component';\nimport {MatToolbarModule} from '@angular/material/toolbar';\nimport {MatExpansionModule} from '@angular/material/expansion';\nimport {BrowserAnimationsModule} from '@angular/platform-browser/animations';\nimport {MatDividerModule} from '@angular/material/divider';\nimport { BrowserComponent } from './components/browser/browser.component';\nimport { DatabaseControlComponent } from './components/database-control/database-control.component';\nimport {MatButtonModule} from '@angular/material/button';\nimport {HttpClientModule} from '@angular/common/http';\nimport { SnippetComponent } from './components/snippset/snippet.component';\nimport {HIGHLIGHT_OPTIONS, HighlightModule} from 'ngx-highlightjs';\nimport {ClipboardModule} from '@angular/cdk/clipboard';\n\n@NgModule({\n declarations: [\n AppComponent,\n BrowserComponent,\n DatabaseControlComponent,\n SnippetComponent\n ],\n imports: [\n BrowserModule,\n MatToolbarModule,\n MatExpansionModule,\n BrowserAnimationsModule,\n MatDividerModule,\n MatButtonModule,\n HttpClientModule,\n HighlightModule,\n ClipboardModule\n ],\n providers: [{\n provide: HIGHLIGHT_OPTIONS,\n useValue: {\n coreLibraryLoader: () => import('highlight.js/lib/core'),\n languages: {\n cypher: () => import('../assets/cypher.js'),\n }\n }\n }],\n bootstrap: [AppComponent]\n})\nexport class AppModule { }\n","import {Injectable} from '@angular/core';\nimport {HttpClient} from '@angular/common/http';\nimport {Observable} from 'rxjs';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class DatabaseService {\n\n constructor(private http: HttpClient) {\n }\n\n public loadPokemon(): Observable {\n return this.http.post('http://localhost:8080/api/pokemon/load', null);\n }\n\n public loadSinnohMap(): Observable {\n return this.http.post('http://localhost:8080/api/sinnoh-map/load', null);\n }\n\n public clearDatabase(): Observable {\n return this.http.delete('http://localhost:8080/api/database');\n }\n}\n","import { enableProdMode } from '@angular/core';\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\n\nimport { AppModule } from './app/app.module';\nimport { environment } from './environments/environment';\n\nif (environment.production) {\n enableProdMode();\n}\n\nplatformBrowserDynamic().bootstrapModule(AppModule)\n .catch(err => console.error(err));\n","function webpackEmptyAsyncContext(req) {\n\t// Here Promise.resolve().then() is used instead of new Promise() to prevent\n\t// uncaught exception popping up in devtools\n\treturn Promise.resolve().then(function() {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t});\n}\nwebpackEmptyAsyncContext.keys = function() { return []; };\nwebpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;\nmodule.exports = webpackEmptyAsyncContext;\nwebpackEmptyAsyncContext.id = \"zn8P\";"],"sourceRoot":"webpack:///"} \ No newline at end of file