Neo4j中文使用手冊(cè)以及例子_第1頁
Neo4j中文使用手冊(cè)以及例子_第2頁
Neo4j中文使用手冊(cè)以及例子_第3頁
Neo4j中文使用手冊(cè)以及例子_第4頁
Neo4j中文使用手冊(cè)以及例子_第5頁
已閱讀5頁,還剩516頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

PAGEPAGE172\o"第

15

Cypher查詢語言"Cypher查詢語言\o"第

4

在Java應(yīng)用中使用Neo4j"在Java應(yīng)用中使用Neo4j\o"第

9

在Python應(yīng)用中使用Neo4j"在Python應(yīng)用中使用Neo4j\o"第

5

Neo4j遠(yuǎn)程客戶端庫"遠(yuǎn)程客戶端訪問庫\o"第

8

多語言支持"多語言支持\o"第

17

Neo4j服務(wù)器"Neo4j服務(wù)器\o"第

18

RESTAPI"RESTAPI目錄前言I.簡(jiǎn)介1.Neo4j的亮點(diǎn)2.圖數(shù)據(jù)庫概要3.Neo4j圖數(shù)據(jù)庫II.教程4.在Java應(yīng)用中使用Neo4j5.Neo4j遠(yuǎn)程客戶端庫6.遍歷查詢框架7.數(shù)據(jù)模型范例8.多語言支持9.在Python應(yīng)用中使用Neo4j10.擴(kuò)展Neo4j服務(wù)器III.參考11.性能12.事務(wù)管理13.數(shù)據(jù)導(dǎo)入14.索引15.Cypher查詢語言16.圖形算法17.Neo4j服務(wù)器18.RESTAPI19.在Python中使用Neo4j嵌入模式IV.操作20.安裝和部署21.配置和調(diào)優(yōu)22.高可用性模式23.備份24.安全25.監(jiān)視服務(wù)器V.工具集26.基于Web的Neo4j圖數(shù)據(jù)庫管理工具27.Neo4j命令行VI.社區(qū)28.社區(qū)支持29.促進(jìn)Neo4j發(fā)展A.聯(lián)機(jī)幫助頁A.1.neo4jA.2.neo4j-shellA.3.neo4j-backupA.4.neo4j-coordinatorA.5.neo4j-coordinator-shellB.常見問題第1章Neo4j的亮點(diǎn)作為一款強(qiáng)健的,可伸縮的高性能數(shù)據(jù)庫,Neo4j最適合完整的企業(yè)部署或者用于一個(gè)輕量級(jí)項(xiàng)目中完整服務(wù)器的一個(gè)子集存在。它包括如下幾個(gè)顯著特點(diǎn):完整的ACID支持高可用性輕易擴(kuò)展到上億級(jí)別的節(jié)點(diǎn)和關(guān)系通過遍歷工具高速檢索數(shù)據(jù)適當(dāng)?shù)腁CID操作是保證數(shù)據(jù)一致性的基礎(chǔ)。Neo4j確保了在一個(gè)事務(wù)里面的多個(gè)操作同時(shí)發(fā)生,保證數(shù)據(jù)一致性。不管是采用嵌入模式還是多服務(wù)器集群部署,都支持這一特性。更多詳細(xì)的介紹,請(qǐng)參考章節(jié):transactions。可靠的圖型存儲(chǔ)可以非常輕松的集成到任何一個(gè)應(yīng)用中。隨著我們開發(fā)的應(yīng)用在運(yùn)營中不斷發(fā)展,性能問題肯定會(huì)逐步凸顯出來,而Neo4j不管應(yīng)用如何變化,他只會(huì)受到計(jì)算機(jī)硬件性能的影響,不受業(yè)務(wù)本身的約束。部署一個(gè)neo4j服務(wù)器便可以承載上億級(jí)的節(jié)點(diǎn)和關(guān)系。當(dāng)然,當(dāng)單節(jié)點(diǎn)無法承載我們的數(shù)據(jù)需求時(shí),我們可以進(jìn)行分布式集群部署,詳細(xì)的細(xì)節(jié),請(qǐng)參考章節(jié):ha。將圖數(shù)據(jù)庫用于存儲(chǔ)關(guān)系復(fù)雜的數(shù)據(jù)是他最大的優(yōu)勢(shì)。通過Neo4j提供的遍歷工具,可以非常高效的進(jìn)行數(shù)據(jù)檢索,每秒可以達(dá)到上億級(jí)的檢索量。一個(gè)檢索操作類似于RDBMS里面的連接(_join_)操作。第2章圖數(shù)據(jù)庫概要這個(gè)章節(jié)包括一個(gè)對(duì)圖數(shù)據(jù)模型的介紹以及將它與其他我們常見的數(shù)據(jù)持久化模型的比較。2.1.什么是圖數(shù)據(jù)庫?圖數(shù)據(jù)庫用圖來存儲(chǔ)數(shù)據(jù),是最接近高性能的一種用于存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)方式之一。讓我們跟隨下面的圖表,用他們來解釋圖數(shù)據(jù)庫相關(guān)概念。我們將跟隨圖表中箭頭方向來讀懂圖想表達(dá)的真正含義。2.1.1.一個(gè)圖由無數(shù)的節(jié)點(diǎn)和關(guān)系組成“一張圖–數(shù)據(jù)記錄在→節(jié)點(diǎn)→包括的→屬性里面”最簡(jiǎn)單的圖是單節(jié)點(diǎn)的,一個(gè)記錄,記錄了一些屬性。一個(gè)節(jié)點(diǎn)可以從單屬性開始,成長(zhǎng)為成千上億,雖然會(huì)有一點(diǎn)點(diǎn)麻煩。從某種意義上講,將數(shù)據(jù)用關(guān)系連接起來分布到不同節(jié)點(diǎn)上才是有意義的。2.1.2.關(guān)系將圖各個(gè)部分組織起來“節(jié)點(diǎn)—被組織→關(guān)系—可以有→屬性”關(guān)系可以將節(jié)點(diǎn)組織成任意的結(jié)構(gòu),允許一張圖被組織成一個(gè)列表,一棵樹,一張地圖,或者一個(gè)復(fù)雜的實(shí)體–這個(gè)實(shí)體本身也是由復(fù)雜的,關(guān)系高度關(guān)聯(lián)的結(jié)構(gòu)組成。2.1.3.用Traversal進(jìn)行數(shù)據(jù)庫查詢“一個(gè)Traversal—導(dǎo)航→一張圖;他—標(biāo)示→路徑—包含→節(jié)點(diǎn)”一次Traversal,你可以理解為是你通過一種算法,從一些開始節(jié)點(diǎn)開始查詢與其關(guān)聯(lián)的節(jié)點(diǎn),比如你想找到“我朋友喜歡但我不喜歡的那首音樂是什么呢?”,又或者“如果斷電了,拿下服務(wù)器的服務(wù)會(huì)首影響?”等等問題。2.1.4.為節(jié)點(diǎn)和關(guān)系建立索引“一個(gè)索引—映射到→屬性—屬于→節(jié)點(diǎn)或者關(guān)系”經(jīng)常,你想通過某一給定的屬性值找到節(jié)點(diǎn)或者關(guān)系。比起通過遍歷我們的圖來書,用索引將會(huì)更加高效。比如“找到用戶名是tony的用戶”。2.1.5.Neo4j是一個(gè)圖數(shù)據(jù)庫“一個(gè)圖數(shù)據(jù)庫—管理→一張圖和與圖相關(guān)的→索引”Neo4j是一個(gè)有商業(yè)支持的開源圖數(shù)據(jù)庫。他被設(shè)計(jì)來用于拿下數(shù)據(jù)不斷高速成長(zhǎng)的數(shù)據(jù)存儲(chǔ),用高效的圖數(shù)據(jù)結(jié)構(gòu)代替?zhèn)鹘y(tǒng)的表設(shè)計(jì)。用Neo4j工作,您的應(yīng)用將得到圖的所有優(yōu)越表現(xiàn),以及您期望的高可靠性。2.2.比較各種數(shù)據(jù)庫模型圖數(shù)據(jù)庫通過在一張圖上存儲(chǔ)節(jié)點(diǎn)和關(guān)系來持久化我們的數(shù)據(jù)結(jié)構(gòu)。比起其他持久化數(shù)據(jù)模型如何呢?因?yàn)閳D是一種常規(guī)數(shù)據(jù)結(jié)構(gòu),讓我們與其他的進(jìn)行一下比較試試看。2.2.1.從圖數(shù)據(jù)庫轉(zhuǎn)換成RDBMS將所有的數(shù)據(jù)用豎立的堆棧表示,并且保持他們直接的關(guān)系,你可以看到下面一張圖。一個(gè)RDBMS被優(yōu)化用于聚合數(shù)據(jù),而Neo4j擅長(zhǎng)于高度關(guān)聯(lián)的數(shù)據(jù)。圖2.1.RDBMS圖2.2.用圖實(shí)現(xiàn)RDBMS模型2.2.2.從圖數(shù)據(jù)庫轉(zhuǎn)換成Key-Value數(shù)據(jù)庫Key-Value模型適合用于簡(jiǎn)單的數(shù)據(jù)或者列表。當(dāng)數(shù)據(jù)之間不斷交互關(guān)聯(lián)時(shí),你更需要一張圖模型。Neo4j讓你能驚醒制作簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)到復(fù)雜,互相連接的數(shù)據(jù)。圖2.3.Key-Value存儲(chǔ)模型K*代表一個(gè)鍵,V*代表一個(gè)值。請(qǐng)注意,某些鍵指向其他鍵以及普通值。圖2.4.用圖實(shí)現(xiàn)Key-Value模型2.2.3.從圖數(shù)據(jù)庫轉(zhuǎn)換成列數(shù)據(jù)庫列式(大表)數(shù)據(jù)庫是Key-Value模型的升級(jí),用“”來允許行數(shù)據(jù)增加。如果存儲(chǔ)一張圖,這個(gè)表將是分層的,關(guān)系也是非常明確的。2.2.4.從圖數(shù)據(jù)庫轉(zhuǎn)換成文檔型數(shù)據(jù)庫文檔型數(shù)據(jù)庫用文檔進(jìn)行層次劃分,而自由的數(shù)據(jù)規(guī)劃也很容易被表示成一顆樹。成長(zhǎng)為一張圖的話,文檔之間的關(guān)聯(lián)你需要更有代表性的數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ),而在Neo4j中,這些關(guān)系是非常容易處理的。圖2.5.文檔型數(shù)據(jù)庫D=文檔,S=子文檔,V=值,D2/S2=關(guān)聯(lián)到(其他)文檔的索引。圖2.6.從圖數(shù)據(jù)庫轉(zhuǎn)換成文檔型數(shù)據(jù)庫第3章Neo4j圖數(shù)據(jù)庫這個(gè)章節(jié)將講述Neo4j模型和行為的更多細(xì)節(jié)。3.1.節(jié)點(diǎn)構(gòu)成一張圖的基本元素是節(jié)點(diǎn)和關(guān)系。在Neo4j中,節(jié)點(diǎn)和關(guān)系都可以包含\o"3.3.

屬性"屬性。節(jié)點(diǎn)經(jīng)常被用于表示一些_實(shí)體_,但依賴關(guān)系也一樣可以表示實(shí)體。下面讓我們認(rèn)識(shí)一個(gè)最簡(jiǎn)單的節(jié)點(diǎn),他只有一個(gè)屬性,屬性名是name,屬性值是Marko:3.2.關(guān)系節(jié)點(diǎn)之間的關(guān)系是圖數(shù)據(jù)庫很重要的一部分。通過關(guān)系可以找到很多關(guān)聯(lián)的數(shù)據(jù),比如節(jié)點(diǎn)集合,關(guān)系集合以及他們的\o"3.3.

屬性"屬性集合。一個(gè)關(guān)系連接兩個(gè)節(jié)點(diǎn),必須有一個(gè)開始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)。因?yàn)殛P(guān)系總是直接相連的,所以對(duì)于一個(gè)節(jié)點(diǎn)來說,與他關(guān)聯(lián)的關(guān)系看起來有輸入/輸出兩個(gè)方向,這個(gè)特性對(duì)于我們遍歷圖非常有幫助:關(guān)系在任一方向都會(huì)被遍歷訪問。這意味著我們并不需要在不同方向都新增關(guān)系。而關(guān)系總是會(huì)有一個(gè)方向,所以當(dāng)這個(gè)方向?qū)δ愕膽?yīng)用沒有意義時(shí)你可以忽略方向。特別注意一個(gè)節(jié)點(diǎn)可以有一個(gè)關(guān)系是指向自己的:為了將來增強(qiáng)遍歷圖中所有的關(guān)系,我們需要為關(guān)系設(shè)置類型。注意關(guān)鍵字type在這可能會(huì)被誤解,你其實(shí)可以把他簡(jiǎn)單的理解為一個(gè)標(biāo)簽而已。下面的例子是一個(gè)有兩種關(guān)系的最簡(jiǎn)單的社會(huì)化網(wǎng)絡(luò)圖。表3.1.使用到的關(guān)系和關(guān)系類型功能實(shí)現(xiàn)getwhoapersonfollowsoutgoingfollowsrelationships,depthonegetthefollowersofapersonincomingfollowsrelationships,depthonegetwhoapersonblocksoutgoingblocksrelationships,depthonegetwhoapersonisblockedbyincomingblocksrelationships,depthone下面的放里是一個(gè)簡(jiǎn)單的文件系統(tǒng),包括一些符號(hào)軟鏈接:根據(jù)你看到的,你在遍歷的時(shí)候會(huì)用到關(guān)系的方向和關(guān)系的類型。WhatHowgetthefullpathofafileincomingfilerelationshipsgetallpathsforafileincomingfileandsymboliclinkrelationshipsgetallfilesinadirectoryoutgoingfileandsymboliclinkrelationships,depthonegetallfilesinadirectory,excludingsymboliclinksoutgoingfilerelationships,depthonegetallfilesinadirectory,recursivelyoutgoingfileandsymboliclinkrelationships3.3.屬性節(jié)點(diǎn)和關(guān)系都可以設(shè)置自己的屬性。屬性是由Key-Value鍵值對(duì)組成,鍵名是字符串。屬性值是要么是原始值,要么是原始值類型的一個(gè)數(shù)組。比如+String+,+int+和i+int[]+都是合法的。注意null不是一個(gè)合法的屬性值。Nulls能代替模仿一個(gè)不存在的Key。表3.2.屬性值類型TypeDescriptionValuerangebooleantrue/falsebyte8-bitinteger-128to127,inclusiveshort16-bitinteger-32768to32767,inclusiveint32-bitinteger-2147483648to2147483647,inclusivelong64-bitinteger-9223372036854775808to9223372036854775807,inclusivefloat32-bitIEEE754floating-pointnumberdouble64-bitIEEE754floating-pointnumberchar16-bitunsignedintegersrepresentingUnicodecharactersu0000touffff(0to65535)StringsequenceofUnicodecharacters如果要了解float/double類型的更多細(xì)節(jié),請(qǐng)參考:JavaLanguageSpecification。3.4.路徑路徑由至少一個(gè)節(jié)點(diǎn),通過各種關(guān)系連接組成,經(jīng)常是作為一個(gè)查詢或者遍歷的結(jié)果。最短的路徑是0長(zhǎng)度的像下面這樣:長(zhǎng)度為1的路徑如下:3.5.遍歷(Traversal)遍歷一張圖就是按照一定的規(guī)則,跟隨他們的關(guān)系,訪問關(guān)聯(lián)的的節(jié)點(diǎn)集合。最多的情況是只有一部分子圖被訪問到,因?yàn)槟阒滥銓?duì)那一部分節(jié)點(diǎn)或者關(guān)系感興趣。Neo4j提供了遍歷的API,可以讓你指定遍歷規(guī)則。最簡(jiǎn)單的設(shè)置就是設(shè)置遍歷是寬度優(yōu)先還是深度優(yōu)先。想對(duì)遍歷框架有一個(gè)深入的了解,請(qǐng)參考章節(jié):tutorial-traversal。想了解更多的Java代碼范例,請(qǐng)參考章節(jié):tutorials-java-embedded-traversal。其他查詢圖的方式還有cypher-query-lang,Cypher和gremlin-plugin,Gremlin。部分II.教程教程這部分將指導(dǎo)我們?nèi)绾谓⒛愕沫h(huán)境并使用Neo4j進(jìn)行開發(fā)。它將從最簡(jiǎn)單的HelloWorld到圖數(shù)據(jù)庫的高級(jí)應(yīng)用逐一介紹。第4章在Java應(yīng)用中使用Neo4j在Java中采用嵌入方式使用Neo4j是非常方便的。在這個(gè)章節(jié)中,你將找到所有你想了解的—從基本環(huán)境的搭建到用你的數(shù)據(jù)做一些實(shí)際有用的事情。在Java應(yīng)用中使用Neo4j是非常容易的。正這個(gè)章節(jié)中你將找到你需要的一切?—?從開發(fā)環(huán)境的建立到用你的數(shù)據(jù)做一些有用的事情。4.1.將Neo4j引入到你的項(xiàng)目工程中在選擇了適合你的平臺(tái)的editions,edition后,只需要引入Neo4j的jars文件到你的工程的構(gòu)造路徑中,你就可以在你的工程中使用Neo4j數(shù)據(jù)庫了。下面的章節(jié)將展示如何完成引入,要么通過直接改變構(gòu)造路徑,要么使用包依賴管理。4.1.1.增加Neo4j的庫文件到構(gòu)造路徑中可以通過下面任意一種方式得到需要的jar文件:解壓Neo4j下載的壓縮包,我們需要使用的jars文件都包括在lib目錄中。直接使用Maven中心倉庫的jars文件。將jars引入到你的項(xiàng)目工程中:JDKtools增加到-classpath中Eclipse右鍵點(diǎn)擊工程然后選擇BuildPath→ConfigureBuildPath。在對(duì)話框中選擇AddExternalJARs,瀏覽到Neo4j的'lib/'目錄并選擇所有的jar文件。另外一種方式是使用UserLibraries。IntelliJIDEA看Libraries,GlobalLibraries,andtheConfigureLibrarydialog了解詳情。NetBeans在工程的Libraries點(diǎn)擊鼠標(biāo)右鍵,選擇AddJAR/Folder,瀏覽到Neo4j的'lib/'目錄選擇里面的所有jar文件。你也可以從工程節(jié)點(diǎn)來管理庫文件。詳細(xì)情況請(qǐng)查看管理一個(gè)工程的classpath。4.1.2.將Neo4j作為一個(gè)依賴添加想總覽一下主要的Neo4j構(gòu)件,請(qǐng)查看editions。列在里面的構(gòu)件都是包含實(shí)際Neo4j實(shí)現(xiàn)的頂級(jí)構(gòu)件。你既可以使用頂級(jí)構(gòu)件也可以直接引入單個(gè)的組件。在這的范例使用的是頂級(jí)構(gòu)件的方式。MavenMavendependency.123456789101112<project>...<dependencies><dependency><groupId>org.neo4j</groupId><artifactId>neo4j</artifactId><version>1.8</version></dependency>...</dependencies>...</project>參數(shù)artifactId可以在editions找到。EclipseandMaven在Eclipse中開發(fā),推薦安裝插件m2eplugin讓Maven管理classpath來代替上面的方案。這樣的話,你既可以通過Maven命令行來編譯你的工程,也可以通過Maven命令自動(dòng)生成一個(gè)Eclipse工作環(huán)境以便進(jìn)行開發(fā)。Ivy確保能解決來自MavenCentral的依賴問題,比如我們?cè)谀愕?ivysettings.xml'文件中使用下面的配置選項(xiàng):1234567891011<ivysettings><settingsdefaultResolver="main"/><resolvers><chainname="main"><filesystemname="local"><artifactpattern="${ivy.settings.dir}/repository/[artifact]-[revision].[ext]"/></filesystem><ibiblioname="maven_central"root="/maven2/"m2compatible="true"/></chain></resolvers></ivysettings>有了這個(gè),你就可以通過增加下面這些內(nèi)容到你的'ivy.xml'中來引入Neo4j:1234567..<dependencies>..<dependencyorg="org.neo4j"name="neo4j"rev="1.8"/>..</dependencies>..參數(shù)name可以在editions找到。Gradle下面的范例演示了用Gradle生成一個(gè)腳本來引入Neo4j庫文件。12345678defneo4jVersion="1.8"applyplugin:'java'repositories{mavenCentral()}dependencies{compile"org.neo4j:neo4j:${neo4jVersion}"}參數(shù)coordinates(在范例中的org.neo4j:neo4j)可以在editions找到。4.1.3.啟動(dòng)和停止為了創(chuàng)建一個(gè)新的數(shù)據(jù)庫或者打開一個(gè)已經(jīng)存在的,你需要實(shí)例化一個(gè)+EmbeddedGraphDatabase+對(duì)象。12graphDb=newGraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);registerShutdownHook(graphDb);注意EmbeddedGraphDatabase實(shí)例可以在多個(gè)線程中共享。然而你不能創(chuàng)建多個(gè)實(shí)例來指向同一個(gè)數(shù)據(jù)庫。為了停止數(shù)據(jù)庫,你需要調(diào)用方法shutdown():1graphDb.shutdown();為了確保Neo4j被正確關(guān)閉,你可以為它增加一個(gè)關(guān)閉鉤子方法:1234567891011121314privatestaticvoidregisterShutdownHook(finalGraphDatabaseServicegraphDb){//RegistersashutdownhookfortheNeo4jinstancesothatit//shutsdownnicelywhentheVMexits(evenifyou"Ctrl-C"the//runningexamplebeforeit'scompleted)Runtime.getRuntime().addShutdownHook(newThread(){@Overridepublicvoidrun(){graphDb.shutdown();}});}如果你只想通過只讀方式瀏覽數(shù)據(jù)庫,請(qǐng)使用EmbeddedReadOnlyGraphDatabase。想通過配置設(shè)置來啟動(dòng)Neo4j,一個(gè)Neo4j屬性文件可以像下面這樣加載:1234GraphDatabaseServicegraphDb=newGraphDatabaseFactory().newEmbeddedDatabaseBuilder("target/database/location").loadPropertiesFromFile(pathToConfig+"perties").newGraphDatabase();或者你可以編程創(chuàng)建你自己的Map<String,String>來代替。想了解更多配置設(shè)置的細(xì)節(jié),請(qǐng)參考:embedded-configuration。4.2.你好,世界正這里可以學(xué)習(xí)如何創(chuàng)建和訪問節(jié)點(diǎn)和關(guān)系。關(guān)于建立工程環(huán)境的信息,請(qǐng)參考:\o"4.1.

將Neo4j引入到你的項(xiàng)目工程中"第4.1節(jié)“將Neo4j引入到你的項(xiàng)目工程中”。從\o"2.1.

什么是圖數(shù)據(jù)庫?"第2.1節(jié)“什么是圖數(shù)據(jù)庫?”中,我們還記得,一個(gè)Neo4j圖數(shù)據(jù)庫由以下幾部分組成:相互關(guān)聯(lián)的節(jié)點(diǎn)有一定的關(guān)系存在在節(jié)點(diǎn)和關(guān)系上面有一些屬性。所有的關(guān)系都有一個(gè)類型。比如,如果一個(gè)圖數(shù)據(jù)庫實(shí)例表示一個(gè)社網(wǎng)絡(luò),那么一個(gè)關(guān)系類型可能叫KNOWS。如果一個(gè)類型叫KNOWS的關(guān)系連接了兩個(gè)節(jié)點(diǎn),那么這可能表示這兩個(gè)人呼吸認(rèn)識(shí)。一個(gè)圖數(shù)據(jù)庫中大量的語義都被編碼成關(guān)系的類型來使用。雖然關(guān)系是直接相連的,但他們也可以不用考慮他們遍歷的方向而互相遍歷對(duì)方。提示范例源代碼下載地址:EmbeddedNeo4j.java4.2.1.準(zhǔn)備圖數(shù)據(jù)庫關(guān)系類型可以通過enum創(chuàng)建。正這個(gè)范例中我們之需要一個(gè)單獨(dú)的關(guān)系類型。下面是我們的定義:1234privatestaticenumRelTypesimplementsRelationshipType{KNOWS}我們頁準(zhǔn)備一些需要用到的參數(shù):1234GraphDatabaseServicegraphDb;NodefirstNode;NodesecondNode;Relationshiprelationship;下一步將啟動(dòng)數(shù)據(jù)庫服務(wù)器了。逐一如果給定的保持?jǐn)?shù)據(jù)庫的目錄如果不存在,那么它會(huì)自動(dòng)創(chuàng)建。12graphDb=newGraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);registerShutdownHook(graphDb);注意:?jiǎn)?dòng)一個(gè)圖數(shù)據(jù)庫是一個(gè)非常重(耗費(fèi)資源)的操作,所以不要每次你需要與數(shù)據(jù)庫進(jìn)行交互操作時(shí)都去啟動(dòng)一個(gè)新的實(shí)例。這個(gè)實(shí)例可以被多個(gè)線程共享。事務(wù)是線程安全的。就像你上面所看到的一樣,我們注冊(cè)了一個(gè)關(guān)閉數(shù)據(jù)庫的鉤子用來確保在JVM退出時(shí)數(shù)據(jù)庫已經(jīng)被關(guān)閉。現(xiàn)在是時(shí)候與數(shù)據(jù)庫進(jìn)行交互了。4.2.2.在一個(gè)事務(wù)中完成多次寫數(shù)據(jù)庫操作所有的寫操作(創(chuàng)建,刪除以及更新)都是在一個(gè)事務(wù)中完成的。這是一個(gè)有意的設(shè)計(jì),因?yàn)槲覀兿嘈攀聞?wù)是使用一個(gè)企業(yè)級(jí)數(shù)據(jù)庫中非常重要的一部分?,F(xiàn)在,在Neo4j中的事務(wù)處理是非常容易的:12345678910Transactiontx=graphDb.beginTx();try{//Updatingoperationsgoheretx.success();}finally{tx.finish();}要了解更多關(guān)于事務(wù)的細(xì)節(jié),請(qǐng)參考:transactions和JavaAPI中的事務(wù)接口。4.2.3.創(chuàng)建一個(gè)小型圖數(shù)據(jù)庫現(xiàn)在,讓我們來創(chuàng)建一些節(jié)點(diǎn)。API是非常直觀的。你也隨意查看在/neo4j/1.8/apidocs/的JavaDocs文檔。它們也被包括正發(fā)行版中。這兒展示了如何創(chuàng)建一個(gè)小型圖數(shù)據(jù)庫,數(shù)據(jù)庫中包括兩個(gè)節(jié)點(diǎn)并用一個(gè)關(guān)系相連,節(jié)點(diǎn)和關(guān)系還包括一些屬性:1234567firstNode=graphDb.createNode();firstNode.setProperty("message","Hello,");secondNode=graphDb.createNode();secondNode.setProperty("message","World!");relationship=firstNode.createRelationshipTo(secondNode,RelTypes.KNOWS);relationship.setProperty("message","braveNeo4j");現(xiàn)在我們有一個(gè)圖數(shù)據(jù)庫看起來像下面這樣:圖4.1.HelloWorld圖數(shù)據(jù)庫4.2.4.打印結(jié)果在我們創(chuàng)建我們的圖數(shù)據(jù)庫后,讓我們從中讀取數(shù)據(jù)并打印結(jié)果。123System.out.print(firstNode.getProperty("message"));System.out.print(relationship.getProperty("message"));System.out.print(secondNode.getProperty("message"));輸出結(jié)果:Hello,braveNeo4jWorld!4.2.5.移除數(shù)據(jù)在這種情況下我們將在提交之前移除數(shù)據(jù):1234//let'sremovethedatafirstNode.getSingleRelationship(RelTypes.KNOWS,Direction.OUTGOING).delete();firstNode.delete();secondNode.delete();注意刪除一個(gè)仍然有關(guān)系的節(jié)點(diǎn),當(dāng)事務(wù)提交是會(huì)失敗。這是為了確保關(guān)系始終有一個(gè)開始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)。4.2.6.關(guān)閉圖數(shù)據(jù)庫最后,當(dāng)應(yīng)用完成后關(guān)閉數(shù)據(jù)庫:1graphDb.shutdown();4.3.帶索引的用戶數(shù)據(jù)庫你有一個(gè)用戶數(shù)據(jù)庫,希望通過名稱查找到用戶。首先,下面這是我們想創(chuàng)建的數(shù)據(jù)庫結(jié)構(gòu):圖4.2.用戶節(jié)點(diǎn)空間預(yù)覽其中,參考節(jié)點(diǎn)連接了一個(gè)用戶參考節(jié)點(diǎn),而真實(shí)的所有用戶都連接在用戶參考節(jié)點(diǎn)上面。提示范例中的源代碼下載地址:EmbeddedNeo4jWithIndexing.java首先,我們定義要用到的關(guān)系類型:12345privatestaticenumRelTypesimplementsRelationshipType{USERS_REFERENCE,USER}然后,我們創(chuàng)建了兩個(gè)輔助方法來處理用戶名稱以及往數(shù)據(jù)庫新增用戶:123456789101112privatestaticStringidToUserName(finalintid){return"user"+id+"@";}privatestaticNodecreateAndIndexUser(finalStringusername){Nodenode=graphDb.createNode();node.setProperty(USERNAME_KEY,username);nodeIndex.add(node,USERNAME_KEY,username);returnnode;}下一步我們將啟動(dòng)數(shù)據(jù)庫:123graphDb=newGraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);nodeIndex=graphDb.index().forNodes("nodes");registerShutdownHook();是時(shí)候新增用戶了:1234567891011121314Transactiontx=graphDb.beginTx();try{//CreateuserssubreferencenodeNodeusersReferenceNode=graphDb.createNode();graphDb.getReferenceNode().createRelationshipTo(usersReferenceNode,RelTypes.USERS_REFERENCE);//CreatesomeusersandindextheirnameswiththeIndexServicefor(intid=0;id<100;id++){NodeuserNode=createAndIndexUser(idToUserName(id));usersReferenceNode.createRelationshipTo(userNode,RelTypes.USER);}通過Id查找用戶:12345intidToFind=45;NodefoundUser=nodeIndex.get(USERNAME_KEY,idToUserName(idToFind)).getSingle();System.out.println("Theusernameofuser"+idToFind+"is"+foundUser.getProperty(USERNAME_KEY));4.4.基本的單元測(cè)試Neo4j的單元測(cè)試的基本模式通過下面的范例來闡釋。要訪問Neo4j測(cè)試功能,你應(yīng)該把neo4j-kernel'tests.jar'新增到你的類路徑中。你可以從MavenCentral:org.neo4j:neo4j-kernel下載到需要的jars。使用Maven作為一個(gè)依賴管理,你通常會(huì)正pom.xml中增加依賴配置:Maven依賴.1234567891011121314<project>...<dependencies><dependency><groupId>org.neo4j</groupId><artifactId>neo4j-kernel</artifactId><version>${neo4j-version}</version><type>test-jar</type><scope>test</scope></dependency>...</dependencies>...</project>_${neo4j-version}是Neo4j的版本號(hào)。_到此,我們已經(jīng)準(zhǔn)備好進(jìn)行單元測(cè)試編碼了。提示范例源代碼下載地址:Neo4jBasicTest.java每一次開始單元測(cè)試之前,請(qǐng)創(chuàng)建一個(gè)干凈的數(shù)據(jù)庫:12345@BeforepublicvoidprepareTestDatabase(){graphDb=newTestGraphDatabaseFactory().newImpermanentDatabaseBuilder().newGraphDatabase();}在測(cè)試完成之后,請(qǐng)關(guān)閉數(shù)據(jù)庫:12345@AfterpublicvoiddestroyTestDatabase(){graphDb.shutdown();}在測(cè)試期間,創(chuàng)建節(jié)點(diǎn)并檢查它們是否存在,并在一個(gè)事務(wù)中結(jié)束寫操作。123456789101112131415161718192021222324252627Transactiontx=graphDb.beginTx();Noden=null;try{n=graphDb.createNode();n.setProperty("name","Nancy");tx.success();}catch(Exceptione){tx.failure();}finally{tx.finish();}//Thenodeshouldhaveanidgreaterthan0,whichistheidofthe//referencenode.assertThat(n.getId(),is(greaterThan(0l)));//Retrieveanodebyusingtheidofthecreatednode.Theid'sand//propertyshouldmatch.NodefoundNode=graphDb.getNodeById(n.getId());assertThat(foundNode.getId(),is(n.getId()));assertThat((String)foundNode.getProperty("name"),is("Nancy"));如果你想查看創(chuàng)建數(shù)據(jù)庫的參數(shù)配置,你可以這樣:12345Map<String,String>config=newHashMap<String,String>();config.put("neostore.nodestore.db.mapped_memory","10M");config.put("string_block_size","60");config.put("array_block_size","300");GraphDatabaseServicedb=newImpermanentGraphDatabase(config);4.5.遍歷查詢了解更多關(guān)于遍歷查詢的信息,請(qǐng)參考:tutorial-traversal。了解更多關(guān)于遍歷查詢范例的信息,請(qǐng)參考:\o"第

7

數(shù)據(jù)模型范例"第7章數(shù)據(jù)模型范例。4.5.1.黑客帝國對(duì)于上面的黑客帝國范例的遍歷查詢,這次使用新的遍歷API:提示范例源代碼下載地址:NewMatrix.java朋友以及朋友的朋友.123456789privatestaticTraversergetFriends(finalNodeperson){TraversalDescriptiontd=Traversal.description().breadthFirst().relationships(RelTypes.KNOWS,Direction.OUTGOING).evaluator(Evaluators.excludeStartPosition());returntd.traverse(person);}讓我們只想一次真實(shí)的遍歷查詢并打印結(jié)果:1234567891011intnumberOfFriends=0;Stringoutput=neoNode.getProperty("name")+"'sfriends:\n";TraverserfriendsTraverser=getFriends(neoNode);for(PathfriendPath:friendsTraverser){output+="Atdepth"+friendPath.length()+"=>"+friendPath.endNode().getProperty("name")+"\n";numberOfFriends++;}output+="Numberoffriendsfound:"+numberOfFriends+"\n";輸出結(jié)果:123456ThomasAnderson'sfriends:Atdepth1=>TrinityAtdepth1=>MorpheusAtdepth2=>CypherAtdepth3=>AgentSmith找到朋友的數(shù)量:4誰編寫了黑客帝國?.12345678910privatestaticTraverserfindHackers(finalNodestartNode){TraversalDescriptiontd=Traversal.description().breadthFirst().relationships(RelTypes.CODED_BY,Direction.OUTGOING).relationships(RelTypes.KNOWS,Direction.OUTGOING).evaluator(Evaluators.includeWhereLastRelationshipTypeIs(RelTypes.CODED_BY));returntd.traverse(startNode);}打印輸出結(jié)果:1234567891011Stringoutput="Hackers:\n";intnumberOfHackers=0;Traversertraverser=findHackers(getNeoNode());for(PathhackerPath:traverser){output+="Atdepth"+hackerPath.length()+"=>"+hackerPath.endNode().getProperty("name")+"\n";numberOfHackers++;}output+="Numberofhackersfound:"+numberOfHackers+"\n";現(xiàn)在我們知道是誰編寫了黑客帝國:123Hackers:Atdepth4=>TheArchitect找到hackers的數(shù)量:1游走一個(gè)有序路徑這個(gè)范例展示了如何通過一個(gè)路徑上下文控制一條路徑的表現(xiàn)。提示范例源代碼下載地址:OrderedPath.java創(chuàng)建一個(gè)圖數(shù)據(jù)庫.12345678NodeA=db.createNode();NodeB=db.createNode();NodeC=db.createNode();NodeD=db.createNode();A.createRelationshipTo(B,REL1);B.createRelationshipTo(C,REL2);C.createRelationshipTo(D,REL3);A.createRelationshipTo(C,REL2);現(xiàn)在,關(guān)系(REL1→REL2→REL3)的順序保存在一個(gè)ArrayList對(duì)象中。當(dāng)遍歷的時(shí)候,Evaluator能針對(duì)它進(jìn)行檢查,確保只有擁有預(yù)定義關(guān)系順序的路徑才會(huì)被包括并返回:定義如何游走這個(gè)路徑.123456789101112131415161718192021222324finalArrayList<RelationshipType>orderedPathContext=newArrayList<RelationshipType>();orderedPathContext.add(REL1);orderedPathContext.add(withName("REL2"));orderedPathContext.add(withName("REL3"));TraversalDescriptiontd=Traversal.description().evaluator(newEvaluator(){@OverridepublicEvaluationevaluate(finalPathpath){if(path.length()==0){returnEvaluation.EXCLUDE_AND_CONTINUE;}RelationshipTypeexpectedType=orderedPathContext.get(path.length()-1);booleanisExpectedType=path.lastRelationship().isType(expectedType);booleanincluded=path.length()==orderedPathContext.size()&&isExpectedType;booleancontinued=path.length()<orderedPathContext.size()&&isExpectedType;returnEvaluation.of(included,continued);}});執(zhí)行一次遍歷查詢并返回結(jié)果.123456Traversertraverser=td.traverse(A);PathPrinterpathPrinter=newPathPrinter("name");for(Pathpath:traverser){output+=Traversal.pathToString(path,pathPrinter);}輸出結(jié)果:1(A)--[REL1]-->(B)--[REL2]-->(C)--[REL3]-->(D)在這種情況下我們使用一個(gè)自定義類來格式化路徑輸出。下面是它的具體實(shí)現(xiàn):12345678910111213141516171819202122232425262728293031staticclassPathPrinterimplementsTraversal.PathDescriptor<Path>{privatefinalStringnodePropertyKey;publicPathPrinter(StringnodePropertyKey){this.nodePropertyKey=nodePropertyKey;}@OverridepublicStringnodeRepresentation(Pathpath,Nodenode){return"("+node.getProperty(nodePropertyKey,"")+")";}@OverridepublicStringrelationshipRepresentation(Pathpath,Nodefrom,Relationshiprelationship){Stringprefix="--",suffix="--";if(from.equals(relationship.getEndNode())){prefix="<--";}else{suffix="-->";}returnprefix+"["+relationship.getType().name()+"]"+suffix;}}為了了解更多關(guān)于Path的有選擇的輸出的細(xì)節(jié),請(qǐng)參考:Traversal類。注意下面的范例使用了一個(gè)已經(jīng)廢棄的遍歷API。它與新的遍歷查詢API共享底層實(shí)現(xiàn),所以它們的性能是一樣的。比較起來它提供的功能非常有限。4.5.2.老的遍歷查詢API這是我們想遍歷查詢的第一個(gè)圖數(shù)據(jù)庫:圖4.3.黑客帝國節(jié)點(diǎn)空間預(yù)覽提示范例源代碼下載地址:Matrix.java朋友以及朋友的朋友.1234567privatestaticTraversergetFriends(finalNodeperson){returnperson.traverse(Order.BREADTH_FIRST,StopEvaluator.END_OF_GRAPH,ReturnableEvaluator.ALL_BUT_START_NODE,RelTypes.KNOWS,Direction.OUTGOING);}讓我們執(zhí)行一次真實(shí)的遍歷查詢并打印結(jié)果:123456789101112intnumberOfFriends=0;Stringoutput=neoNode.getProperty("name")+"'sfriends:\n";TraverserfriendsTraverser=getFriends(neoNode);for(NodefriendNode:friendsTraverser){output+="Atdepth"+friendsTraverser.currentPosition().depth()+"=>"+friendNode.getProperty("name")+"\n";numberOfFriends++;}output+="Numberoffriendsfound:"+numberOfFriends+"\n";下面是輸出結(jié)果:123456ThomasAnderson的朋友們:Atdepth1=>TrinityAtdepth1=>MorpheusAtdepth2=>CypherAtdepth3=>AgentSmith一共找到朋友數(shù)量:4是誰編寫了黑客帝國呢?12345678910111213141516privatestaticTraverserfindHackers(finalNodestartNode){returnstartNode.traverse(Order.BREADTH_FIRST,StopEvaluator.END_OF_GRAPH,newReturnableEvaluator(){@OverridepublicbooleanisReturnableNode(finalTraversalPositioncurrentPos){return!currentPos.isStartNode()&¤tPos.lastRelationshipTraversed().isType(RelTypes.CODED_BY);}},RelTypes.CODED_BY,Direction.OUTGOING,RelTypes.KNOWS,Direction.OUTGOING);}輸出結(jié)果:123456789101112Stringoutput="Hackers:\n";intnumberOfHackers=0;Traversertraverser=findHackers(getNeoNode());for(NodehackerNode:traverser){output+="Atdepth"+traverser.currentPosition().depth()+"=>"+hackerNode.getProperty("name")+"\n";numberOfHackers++;}output+="Numberofhackersfound:"+numberOfHackers+"\n";現(xiàn)在我們知道是誰編寫了黑客帝國:123Hackers:Atdepth4=>TheArchitect找到hackers的數(shù)量:14.5.3.在遍歷查詢中的唯一路徑這個(gè)范例演示了節(jié)點(diǎn)唯一性的使用。下面是一個(gè)想象的有多個(gè)負(fù)責(zé)人的領(lǐng)域圖,這些負(fù)責(zé)人有它們?cè)黾拥膶櫸?,而這些寵物又生產(chǎn)了它的后代。圖4.4.后代范例圖為了返回Pet0的所有后代,要求與Pet0必須有owns和Principal1關(guān)系(實(shí)際上只有Pet1和Pet3),遍歷查詢的Uniqueness應(yīng)該設(shè)置成NODE_PATH來代替默認(rèn)的NODE_GLOBAL以至于節(jié)點(diǎn)可以被遍歷不止一次,而且那些有不同節(jié)點(diǎn)但能有一些相同的路徑(比如開始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn))也能被返回。1234567891011121314151617finalNodetarget=data.get().get("Principal1");TraversalDescriptiontd=Traversal.description().uniqueness(Uniqueness.NODE_PATH).evaluator(newEvaluator(){@OverridepublicEvaluationevaluate(Pathpath){if(path.endNode().equals(target)){returnEvaluation.INCLUDE_AND_PRUNE;}returnEvaluation.EXCLUDE_AND_CONTINUE;}});Traverserresults=td.traverse(start);這將返回下面的路徑:12(3)--[descendant,0]-->(1)<--[owns,3]--(5)(3)--[descendant,2]-->(4)<--[owns,5]--(5)在path.toString()的默認(rèn)實(shí)現(xiàn)中,(1)--[knows,2]-->(4)表示一個(gè)ID=1的節(jié)點(diǎn)通過一個(gè)ID=2,關(guān)系類型為knows的關(guān)系連接到了一個(gè)ID=4的節(jié)點(diǎn)上。讓我們從一個(gè)舊的中創(chuàng)建一個(gè)新的TraversalDescription,并且設(shè)置uniqueness為NODE_GLOBAL來查看它們之間的區(qū)別。提示TraversalDescription對(duì)象是不變的,因此我們必須使用一個(gè)新的實(shí)例來返回新的uniqueness設(shè)置。12TraversalDescriptionnodeGlobalTd=td.uniqueness(Uniqueness.NODE_GLOBAL);results=nodeGlobalTd.traverse(start);現(xiàn)在只有一條路徑返回:1(3)--[descendant,0]-->(1)<--[owns,3]--(5)4.5.4.社交網(wǎng)絡(luò)注意:下面的范例使用了處于實(shí)驗(yàn)階段的遍歷查詢API。社交網(wǎng)絡(luò)(在互聯(lián)網(wǎng)上也被稱為社交圖)是天然的用圖來表示的模型。下面的范例演示了一個(gè)非常簡(jiǎn)單的社交模型,它連接了朋友并關(guān)注了好友動(dòng)態(tài)。提示范例源代碼下載地址:socnet簡(jiǎn)單的社交模型圖4.5.社交網(wǎng)絡(luò)數(shù)據(jù)模型一個(gè)社交網(wǎng)絡(luò)的數(shù)據(jù)模型是簡(jiǎn)漂亮的:有名稱的Persons和有時(shí)間戳文本的StatusUpdates。這些實(shí)體然后通過特殊的關(guān)系連接在一起。Personfriend:連接兩個(gè)不同Person實(shí)例的關(guān)系(不能連接自己)status:連接到最近的StatusUpdateStatusUpdatenext:指向在主線上的下一個(gè)StatusUpdate,是在當(dāng)前這個(gè)狀態(tài)更新之前發(fā)生的狀態(tài)圖實(shí)例一個(gè)Person的StatusUpdate列表是一個(gè)鏈表。表頭(最近動(dòng)態(tài))可以通過下一個(gè)status找到。每一個(gè)隨后的StatusUpdate都通過關(guān)系next相連。這是一個(gè)AndreasKollegger微博記錄圖早上走路上班的范例:為了讀取狀態(tài)更新情況,我們可以創(chuàng)建一個(gè)遍歷查詢,比如:123TraversalDescriptiontraversal=Traversal.description().depthFirst().relationships(NEXT);這給了我們一個(gè)遍歷查詢,它將從一個(gè)StatusUpdate開始,并一直跟隨狀態(tài)的主線直到它們運(yùn)行結(jié)束。遍歷查詢是懶加載模式所以當(dāng)我們處理成千上萬狀態(tài)的時(shí)候性能一樣很好?—?除非我們真實(shí)使用它們,否在它們不會(huì)被加載?;顒?dòng)流一旦我們有了朋友,而且它們有了狀態(tài)消息,我們可能想讀取我們的朋友的消息動(dòng)態(tài),按時(shí)間倒序排列?—?最新的動(dòng)態(tài)在前面。為了實(shí)現(xiàn)這個(gè),我們可以通過下面幾個(gè)步驟:抓取所有的好友動(dòng)態(tài)放入一個(gè)列表?—?最新的排前面。對(duì)列表進(jìn)行排序。返回列表中的第一個(gè)記錄。如果第一個(gè)迭代器為空,則把它從列表移除。否則,在這個(gè)迭代器中獲取下一個(gè)記錄。跳轉(zhuǎn)到步驟2直到在列表中沒有任何記錄。這個(gè)隊(duì)列看起來像這樣。代碼實(shí)現(xiàn)像這樣:1234567891011121314PositionedIterator<StatusUpdate>first=statuses.get(0);StatusUpdatereturnVal=first.current();if(!first.hasNext()){statuses.remove(0);}else{first.next();sort();}returnreturnVal;4.6.領(lǐng)域?qū)嶓w這個(gè)地方演示了當(dāng)使用Neo4j時(shí)控制領(lǐng)域?qū)嶓w的一個(gè)方法。使用的原則是將實(shí)體封裝到節(jié)點(diǎn)上(這個(gè)方法也可以用在關(guān)系上)。提示范例源代碼下載地址:Person.java馬上,保存節(jié)點(diǎn)并且讓它在包里可以被訪問:1234567891011privatefinalNodeunderlyingNode;Person(NodepersonNode){this.underlyingNode=personNode;}protectedNodegetUnderlyingNode(){returnunderlyingNode;}分配屬性給節(jié)點(diǎn):1234publicStringgetName(){return(String)underlyingNode.getProperty(NAME);}確保重載這些方法:123456789101112131415161718@OverridepublicinthashCode(){returnunderlyingNode.hashCode();}@Overridepublicbooleanequals(Objecto){returnoinstanceofPerson&&underlyingNode.equals(((Person)o).getUnderlyingNode());}@OverridepublicStringtoString(){return"Person["+getName()+"]";}4.7.圖算法范例提示范例源代碼下載地址:PathFindingExamplesTest.java計(jì)算正連個(gè)節(jié)點(diǎn)之間的最短路徑(最少數(shù)目的關(guān)系):12345678910111213141516NodestartNode=graphDb.createNode();NodemiddleNode1=graphDb.createNode();NodemiddleNode2=graphDb.createNode();NodemiddleNode3=graphDb.createNode();NodeendNode=graphDb.createNode();createRelationshipsBetween(startNode,middleNode1,endNode);createRelationshipsBetween(startNode,middleNode2,middleNode3,endNode);//WillfindtheshortestpathbetweenstartNodeandendNodevia//"MY_TYPE"relationships(inOUTGOINGdirection),likef.ex:////(startNode)-->(middleNode1)-->(endNode)//PathFinder<Path>finder=GraphAlgoFactory.shortestPath(Traversal.expanderForTypes(ExampleTypes.MY_TYPE,Direction.OUTGOING),15);Iterable<Path>paths=finder.findAllPaths(startNode,endNode);使用迪科斯徹(Dijkstra)算法解決有向圖中任意兩個(gè)頂點(diǎn)之間的最短路徑問題。1234567PathFinder<WeightedPath>finder=GraphAlgoFactory.dijkstra(Traversal.expanderForTypes(ExampleTypes.MY_TYPE,Direction.BOTH),"cost");WeightedPathpath=finder.findSinglePath(nodeA,nodeB);//Gettheweightforthefoundpathpath.weight();使用A*算法是解決靜態(tài)路網(wǎng)中求解最短路最有效的方法。這兒是我們的范例圖:123456789101112131415161718192021NodenodeA=createNode("name","A","x",0d,"y",0d);NodenodeB=createNode("name","B","x",7d,"y",0d);NodenodeC=createNode("name","C","x",2d,"y",1d);RelationshiprelAB=createRelationship(nodeA,nodeC,"length",2d);RelationshiprelBC=createRelationship(nodeC,nodeB,"length",3d);RelationshiprelAC=createRelationship(nodeA,nodeB,"length",10d);EstimateEvaluator<Double>estimateEvaluator=newEstimateEvaluator<Double>(){publicDoublegetCost(finalNodenode,finalNodegoal){doubledx=(Double)node.getProperty("x")-(Double)goal.getProperty("x");doubledy=(Double)node.getProperty("y")-(Double)goal.getProperty("y");doubleresult=Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2));returnresult;}};PathFinder<WeightedPath>astar=GraphAlgoFactory.aStar(Traversal.expanderForAllTypes(),CommonEvaluators.doubleCostEvaluator("length"),estimateEvaluator);WeightedPathpath=astar.findSinglePath(nodeA,nodeB);4.8.讀取一個(gè)管理配置屬性EmbeddedGraphDatabase類包括了一個(gè)/neo4j/1.8/apidocs/org/neo4j/kernel/EmbeddedGraphDatabase.html#getManagementBean%28java.lang.Class%29[方便的方法]來獲取Neo4j管理用的beans。一般JMX服務(wù)也能使用,但比起你自己編碼不如使用這概述的方法。提示范例源代碼下載地址:JmxTest.java這個(gè)范例演示了如何得到一個(gè)圖數(shù)據(jù)庫的開始時(shí)間:12345678privatestaticDategetStartTimeFromManagementBean(GraphDatabaseServicegraphDbService){GraphDatabaseAPIgraphDb=(GraphDatabaseAPI)graphDbService;Kernelkernel=graphDb.getSingleManagementBean(Kernel.class);DatestartTime=kernel.getKernelStartTime();returnstartTime;}不同的Neo4j版本,你將使用不同的管理beans設(shè)置。了解所有Neo4j版本的信息,請(qǐng)參考:org.neo4j.jmx。了解Neo4j高級(jí)版和企業(yè)版的信息,請(qǐng)參考:org.neo4j.management。4.9.OSGi配置4.9.1.SimpleOSGiActivator腳本在OSGi關(guān)聯(lián)的上下文比如大量的應(yīng)用服務(wù)器(e.g.Glassfish)和基于Eclipse的系統(tǒng)中,Neo4j能被明確地建立起來而不是通過Java服務(wù)加載機(jī)制來發(fā)現(xiàn)。4.9.1.SimpleOSGiActivator腳本如同在下面的范例中看到的一樣,為了代替依賴Neo4j內(nèi)核的類加載,Neo4jBundle被作為庫bundles,而像IndexProviders和CacheProviders這樣的服務(wù)被明確地實(shí)例化,配置和注冊(cè)了秩序。只需要確保必要的jars,所以所有必須的類都被導(dǎo)出并且包括這Activator。1234567891011121314151617181920212223242526272829303132333435363738394041424publicclassNeo4jActivatorimplementsBundleActivator{privatestaticGraphDatabaseServicedb;privateServiceRegistrationserviceRegistration;privateServiceR

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論