java session使用_使用Neo4j和Java进行大数据分析 第2部分
本文的第一部分介紹了Neo4j及其Cypher查詢語言。如果您已經閱讀了第1部分,那么您已經了解了為什么Neo4j和其他圖形數據庫特別受社交圖形或網絡中用戶之間關系建模的影響。您還在開發環境中安裝了Neo4j,并概述了使用此數據存儲的基本概念 - 即節點和關系。
然后,我們使用Cypher查詢語言對Neo4j中的一個家庭進行建模,包括年齡,性別和家庭成員之間的關系等個人屬性。我們創建了一些朋友來擴大我們的社交圖,然后添加鍵/值對來生成每個用戶看過的電影列表。最后,我們查詢了我們的數據,使用圖形分析來搜索一個用戶沒有看到但可能喜歡的電影。
Cypher查詢語言與SQL等傳統數據查詢語言不同。Cypher并沒有考慮像表和外鍵關系這樣的事情,而是強迫您考慮節點,節點之間的自然關系以及各個節點之間可以在各個關系之間進行的各種遍歷。使用Cypher,您可以創建自己的心理模型,了解真實世界的實體如何相互關聯。需要一些練習來擅長編寫Cypher查詢,但是一旦你理解了它們的工作方式,即使非常復雜的查詢也是有意義的。
在使用Cypher查詢語言對Neo4j中的社交圖建模并使用該社交圖編寫查詢后,編寫Java代碼以對該圖執行查詢非常簡單。在本文中,您將學習如何將Neo4j與Java Web客戶端應用程序集成,您可以使用它來查詢我們在第1部分中創建的社交圖。
設置您的Neo4j項目
我們的第一步是創建一個新的Maven項目:
mvn archetype:generate -DgroupId=com.geekcap.javaworld -DartifactId=neo4j-example -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false打開您的pom.xml文件并添加Neo4j驅動程序,在撰寫本文時版本為1.4.1:
<dependency><groupId>org.neo4j.driver</groupId><artifactId>neo4j-java-driver</artifactId><version>1.4.1</version></dependency>創建一個Neo4j驅動程序
接下來,創建一個Neo4j Driver,如下所示:
Driver driver = GraphDatabase.driver( "bolt://localhost:7687", AuthTokens.basic("neo4j", "neo4j"));本GraphDatabase類有一個叫做靜態方法driver()接受一個連接Neo4j的URL和AuthToken。您可以使用默認用戶名和密碼“neo4j” 創建基本AuthToken。
在Driver與Neo4j的促進通信。我們通過要求Driver創建Session對象來執行查詢,如下所示:
Session session = driver.session();Session界面
該org.neo4j.driver.v1.Session接口對Neo4j執行事務。在最簡單的形式中,我們可以執行繼承自的run()方法。然后,將開始一個事務,運行我們的語句,并提交該事務。Sessionorg.neo4j.driver.v1.StatementRunnerSession
該StatementRunner接口定義了的幾個變型run()方法。這是我們將使用的那個:
StatementResult run(String statementTemplate, Map<String,Object> statementParameters)聲明參數
該statementTemplate是一個包含我們的Cypher查詢的String,statementParameters包括我們將使用的命名參數。例如,我們可能想要創建具有指定名稱和年齡的Person:
session.run("CREATE (person: Person {name: {name}, age: {age}})", parameters("name", person.getName(), "age", person.getAge()));{name}和{age}命名,可以通過傳遞解析為String值的Map。每個String都包含屬性的名稱,并且必須與模板中的值匹配。該parameters方法通常從Values對象靜態導入:
import static org.neo4j.driver.v1.Values.parameters管理交易
一個Session已經完成后,你需要通過調用它的close()方法來關閉。為方便起見,該Session對象實現了java.lang.AutoCloseable接口,因此從Java 7開始,您可以在try-with-resources語句中執行它,例如:
try (Session session = driver.session()) {session.run("CREATE (person: Person {name: {name}, age: {age}})",parameters("name", person.getName(), "age", person.getAge())); }最后,如果您正在執行的是要約束到一個單一事務的多條語句,你可以自由地繞過Session的run()方法的自動交易管理和明確自己管理的事務。例如:
try (Session session = driver.session()) {try (Transaction tx = session.beginTransaction()) {tx.run("CREATE (person: Person {name: {name}, age: {age}})",parameters("name", person.getName(), "age", person.getAge()));tx.success();} }該調用Session.beginTransaction()返回一個Transaction可用于運行Cypher語句的對象。執行Cypher語句后,必須調用tx.success()或try-with-resources語句將回滾事務。該Transaction實現AutoCloseable。如果事務被標記為成功(通過調用success()),則提交事務; 否則交易將被回滾。您可以通過調用Transaction的failure()方法明確失敗交易。
記錄對象
您可能已經觀察到Session和Transaction類中的run()方法都返回一個StatementResult實例。StatementResult接口可以訪問Record的列表,Record對象可以有一個或多個Value對象。
與從JDBC的ResultSet檢索值類似, Record允許您通過索引或按名稱檢索值。返回的Value對象可以通過調用Node.asNode()方法或原語(如 String或整數),通過調用其他asXXX()方法之一轉換為Neo4j 。前面幾節中的示例主要返回節點,但最后一個示例將一個人的名稱作為String返回。這就是為什么該Value對象在其返回類型中提供靈活性的原因。
Java中的示例應用程序
現在我們將學習到目前為止所學到的知識,并將Java中的示例應用程序組合在一起。基于第1部分中的建模和查詢示例,此應用程序創建Person對象,查找所有Person對象,查找a的所有朋友Person,并查找Person已看過的所有電影。
清單1和清單2創建了定義 Person和a的Java類Movie。清單3顯示了我們的測試類的源代碼:Neo4jClient。
清單1. Person.java
package com.geekcap.javaworld.neo4j.model;public class Person {private String name;private int age;public Person() {}public Person(String name) {this.name = name;}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }清單2. Movie.java
package com.geekcap.javaworld.neo4j.model;public class Movie {private String title;private int rating;public Movie() {}public Movie(String title) {this.title = title;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public int getRating() {return rating;}public void setRating(int rating) {this.rating = rating;} }清單3. Neo4jClient.java
package com.geekcap.javaworld.neo4j;import com.geekcap.javaworld.neo4j.model.Movie; import com.geekcap.javaworld.neo4j.model.Person; import org.neo4j.driver.v1.*; import org.neo4j.driver.v1.types.Node;import java.util.HashSet; import java.util.Set;import static org.neo4j.driver.v1.Values.parameters;public class Neo4jClient {/*** Neo4j Driver, used to create a session that can execute Cypher queries*/private Driver driver;/*** Create a new Neo4jClient. Initializes the Neo4j Driver.*/public Neo4jClient() {// Create the Neo4j driverdriver = GraphDatabase.driver( "bolt://localhost:7687", AuthTokens.basic("neo4j", "neo4j"));}/*** Create a new Person.* @param person The Person to create*/public void createPerson(Person person) {// Create a Neo4j session. Because the Session object is AutoCloseable, we can use a try-with-resources statementtry (Session session = driver.session()) {// Execute our create Cypher querysession.run("CREATE (person: Person {name: {name}, age: {age}})",parameters("name", person.getName(), "age", person.getAge()));}}/*** Finds all Person objects in the Neo4j database.* @return A set of all Person objects in the Neo4j database.*/public Set<Person> findAllPeople() {// Create a set to hold our peopleSet<Person> people = new HashSet<>();// Create a Neo4j sessiontry (Session session = driver.session()) {// Execute our query for all Person nodesStatementResult result = session.run("MATCH(person:Person) RETURN person");// Iterate over the responsefor (Record record: result.list()) {// Load the Neo4j node from the record by the name "person", from our RETURN statement aboveNode person = record.get("person").asNode();// Build a new person object and add it to our result setPerson p = new Person();p.setName(person.get("name").asString());if (person.containsKey("age")) {p.setAge(person.get("age").asInt());}people.add(p);}}// Return the set of peoplereturn people;}/*** Returns the friends of the requested person.** @param person The person for which to retrieve all friends* @return A Set that contains all Person objects for which there is a FRIEND relationship from* the specified person*/public Set<Person> findFriends(Person person) {// A Set to hold our responseSet<Person> friends = new HashSet<>();// Create a session to Neo4jtry (Session session = driver.session()) {// Execute our queryStatementResult result = session.run("MATCH (person: Person {name: {name}})-[:FRIEND]-(friend: Person) RETURN friend",parameters("name", person.getName()));// Iterate over our responsefor (Record record: result.list()) {// Create a PersonNode node = record.get("friend").asNode();Person friend = new Person(node.get("name").asString());// Add the person to the friend setfriends.add(friend);}}// Return the set of friendsreturn friends;}/*** Find all movies (with rating) seen by the specified Person.** @param person The Person for which to find movies seen* @return A Set of Movies (with ratings)*/public Set<Movie> findMoviesSeenBy(Person person) {Set<Movie> movies = new HashSet<>();try (Session session = driver.session()) {// Execute our queryStatementResult result = session.run("MATCH (person: Person {name: {name}})-[hasSeen:HAS_SEEN]-(movie:Movie) RETURN movie.title, hasSeen.rating",parameters("name", person.getName()));// Iterate over our responsefor (Record record: result.list()) {Movie movie = new Movie(record.get("movie.title").asString());movie.setRating(record.get("hasSeen.rating").asInt());movies.add(movie);}}return movies;}/*** Helper method that prints a person set to the standard output.* @param people The set of Person objects to print to the standard output*/public static void printPersonSet(Set<Person> people) {for (Person person: people) {StringBuilder sb = new StringBuilder("Person: ");sb.append(person.getName());if (person.getAge()>0) {sb.append(" is " + person.getAge() + " years old");}System.out.println(sb);}}/*** Test methods*/public static void main(String ... args) {Neo4jClient client = new Neo4jClient();client.createPerson(new Person("Duke", 22));Set<Person> people = client.findAllPeople();System.out.println("ALL PEOPLE");printPersonSet(people);Set<Person> friendsOfMichael = client.findFriends(new Person("Michael"));System.out.println("FRIENDS OF MICHAEL");printPersonSet(friendsOfMichael);Set<Movie> moviesSeenByMichael = client.findMoviesSeenBy(new Person("Michael"));System.out.println("MOVIES MICHAEL HAS SEEN:");for (Movie movie: moviesSeenByMichael) {System.out.println("Michael gave the movie " + movie.getTitle() + " a rating of " + movie.getRating());}} }示例app:Neo4j客戶端類
在Neo4jClient類在其構造中創建的Neo4j Driver。然后它的方法使用Driver來創建一個Session對象以執行Cypher查詢。createPerson()方法使用“name”和“age”的命名參數執行Cypher查詢CREATE (person:Person {...})。parameters()方法將這些參數綁定到指定Person的名稱和年齡屬性。
findAllPeople()方法查找Person數據庫中的所有對象。請注意,此方法會返回所有人,因此如果您有很多人,則可能需要向響應中添加LIMIT 。這是一個例子:
MATCH (person:Person) RETURN person LIMIT 25在這種情況下,我們返回完整Person節點,因此我從Record中獲取“person”并使用Noded的asNode()方法來轉換。
findFriends()方法執行相同的操作,但它執行不同的Cypher查詢:
MATCH (person: Person {name: {name}})-[:FRIEND]-(friend: Person) RETURN friend我們要求具有指定名稱的人,然后查找該人FRIEND的關系,找到所有Person節點,為每個節點命名為“朋友”。因此,當我們從Record中檢索響應時,我們要求“朋友”并將其轉換為Node。
最后,該findMoviesSeenBy()方法執行以下Cypher查詢:
MATCH (person: Person {name: {name}})-[hasSeen:HAS_SEEN]-(movie:Movie) RETURN movie.title, hasSeen.rating此查詢從指定人員開始,并遵循HAS_SEEN與Movie節點的所有關系。然后它返回電影標題屬性movie.title和評級為hasSeen.rating。
為了做到這一點,我們必須在我們的HAS_SEEN關系中指定一個變量名hasSeen。因為我們要求電影標題和評級,我們從以下各項中單獨檢索Record::
record.get("movie.title").asString() record.get("hasSeen.rating").asInt()該main()方法創建一個新的Neo4jClient,創建一個22歲的名為“Duke”(提示:就像Java一樣)的Person。它找到了邁克爾的朋友和他所見過的電影。
清單4顯示了Maven pom.xml文件,我們用它來構建和運行我們的應用程序。
清單4. Neo4jClient應用程序的Maven POM
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.geekcap.javaworld</groupId><artifactId>neo4j-example</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><name>neo4j-example</name><url>http://maven.apache.org</url><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- Import Neo4j --><dependency><groupId>org.neo4j.driver</groupId><artifactId>neo4j-java-driver</artifactId><version>1.4.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.0.2</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><mainClass>com.geekcap.javaworld.neo4j.Neo4jClient</mainClass></manifest></archive></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy</id><phase>install</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/lib</outputDirectory></configuration></execution></executions></plugin></plugins></build> </project>此pom.xml文件導入neo4j-java-driver依賴項,然后定義三個插件:
- maven-compiler-plugin將Java構建版本設置為1.8。
- maven-jar-plugin使得主類設置為可執行的JAR文件,com.geekcap.javaworld.neo4j.Neo4jClient并包含libJAR文件目錄中的所有文件CLASSPATH。
- maven-dependency-plugin將所有依賴項復制到項目構建目錄的lib文件夾中。
構建并運行您的Neo4j客戶端應用程序
您現在可以使用以下命令構建Neo4j客戶端應用程序:
mvn clean install您可以target使用以下命令從目錄運行它:
java -jar neo4j-example-1.0-SNAPSHOT.jar您應該看到類似于以下內容的輸出:
ALL PEOPLE Person: Steven is 45 years old Person: Jordyn Person: Michael is 16 years old Person: Katie Person: Koby Person: Duke is 22 years old Person: Grant Person: Rebecca is 7 years old Person: Linda Person: Charlie is 16 years old FRIENDS OF MICHAEL Person: Charlie Person: Grant Person: Koby MOVIES MICHAEL HAS SEEN: Michael gave movie Avengers a rating of 5務必導航到您的Neo4j Web界面并執行一些查詢!您應該看到Duke已創建并能夠驗證結果。
第2部分的結論
Neo4j是一個管理高度相關數據的圖形數據庫。我們通過回顧圖形數據庫的需求開始了這種探索,尤其是在查詢關系中三個以上的分離度時。在開發環境中使用Neo4j進行設置后,我們花了大部分時間來了解Neo4j的Cypher查詢語言。我們建立了一個家庭關系網絡,并使用Cypher查詢了這些關系。我們在該文章中的重點是學習如何以圖形方式思考。這是Neo4j的強大功能,也是大多數開發人員掌握的最具挑戰性的功能。
在第2部分中,您學習了如何編寫連接到Neo4j并執行Cypher查詢的Java應用程序。我們采用最簡單(手動)的方法將Java與Neo4j集成。一旦掌握了基礎知識,您可能想要探索將Java與Neo4j集成的更高級方法 - 例如使用Neo4j的對象圖形映射(OGM)庫,Neo4j-OGM和Spring Data。
總結
以上是生活随笔為你收集整理的java session使用_使用Neo4j和Java进行大数据分析 第2部分的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 改变bantchsize发现loss增大
- 下一篇: python类定义全局变量_python