在Python中使用Neo4j數(shù)據(jù)庫(kù)的教程
一個(gè)快速的REST例子
首先來看些基本知識(shí)。如果沒有服務(wù)API,Neo4j就不能支持其他語言。該接口提供一組基于JSON消息格式的RESTful Web服務(wù)和一個(gè)全面的發(fā)現(xiàn)機(jī)制。使用中使用這個(gè)接口的最快和最容易的方法是通過使用cURL:
$ curl http://localhost:7474/db/data/ { "extensions" : { }, "node" : "http://localhost:7474/db/data/node", "node_index" : "http://localhost:7474/db/data/index/node", "relationship_index" : "http://localhost:7474/db/data/index/relationship", "extensions_info" : "http://localhost:7474/db/data/ext", "relationship_types" : "http://localhost:7474/db/data/relationship/types", "batch" : "http://localhost:7474/db/data/batch", "cypher" : "http://localhost:7474/db/data/cypher", "transaction" : "http://localhost:7474/db/data/transaction", "neo4j_version" : "2.0.0-M03" }
從這個(gè)端點(diǎn)返回JSON對(duì)象包含一組資源名稱和URI下可以找到的Cypher端點(diǎn)。在消息載荷中接受傳送來的Cyper請(qǐng)求并執(zhí)行這些查詢,在HTTP響應(yīng)中返回結(jié)果。
正是這種REST API接口,使得現(xiàn)在已有的各種Neo4j驅(qū)動(dòng)得以建立。py2neo提供了這些REST資源的簡(jiǎn)單封裝,這使Python應(yīng)用程序開發(fā)者可以放心使用Neo4j而不用考慮底層的客戶機(jī)-服務(wù)器協(xié)議。
一個(gè)簡(jiǎn)單的應(yīng)用
為實(shí)際驗(yàn)證py2neo,我們將著眼于建立一個(gè)簡(jiǎn)單的用于存儲(chǔ)姓名和電子郵件地址的通訊錄管理系統(tǒng)。我們自然會(huì)使用節(jié)點(diǎn)來模擬每一個(gè)獨(dú)立實(shí)體,但它是要記住,Neo4j沒有類型的概念。類型是從周圍的關(guān)系和屬性推斷來的。
下面的關(guān)系圖中人顯示為紅色、電子郵件地址節(jié)點(diǎn)顯示為藍(lán)色。這些當(dāng)然是純粹的邏輯演示節(jié)點(diǎn),但數(shù)據(jù)本身并沒有區(qū)別。
我們的應(yīng)用程序?qū)⑼瓿蓛蓚€(gè)功能:添加新的聯(lián)系人信息和檢索聯(lián)系人的完整列表。為此,我們將創(chuàng)建一個(gè)Person類包裝Py2neoNodeobject,這使我們有一個(gè)底層處理的實(shí)現(xiàn)且留出用戶級(jí)的功能。上圖中的ROOT節(jié)點(diǎn)是指上圖中一個(gè)固定的參考點(diǎn),我們沿著這個(gè)點(diǎn)開始。
讓我們直接看看代碼。下面是一個(gè)完整的小型應(yīng)用。這個(gè)程序允許添加新的名字與一個(gè)或者更多email地址相連接的以及提供了一個(gè)容易的方式來顯示這些連接信息的一個(gè)命令行工具。沒有參數(shù)的運(yùn)行是顯示使用模式,而且這個(gè)唯一的依賴只是需要一個(gè)本地未修改的Neo4j實(shí)例(instance)而已。
#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import print_function import sys from py2neo import neo4j, node, rel graph_db = neo4j.GraphDatabaseService() class Person(object): _root = graph_db.get_or_create_indexed_node("reference", "contacts", "root") @classmethod def create(cls, name, *emails): person_node, _ = graph_db.create(node(name=name), rel(cls._root, "PERSON", 0)) for email in emails: graph_db.create(node(email=email), rel(cls._root, "EMAIL", 0), rel(person_node, "EMAIL", 0)) return Person(person_node) @classmethod def get_all(cls): return [Person(person.end_node) for person in cls._root.match("PERSON")] def __init__(self, node): self._node = node def __str__(self): return self.name + "\n" + "\n".join(" <{0}>" .format(email) for email in self.emails) @property def name(self): return self._node["name"] @property def emails(self): return [rel.end_node["email"] for rel in self._node.match("EMAIL")] if __name__ == "__main__": if len(sys.argv) < 2: app = sys.argv[0] print("Usage: {0} add <name> <email> [<email>...]".format(app)) print(" {0} list".format(app)) sys.exit() method = sys.argv[1] if method == "add": print(Person.create(*sys.argv[2:])) elif method == "list": for person in Person.get_all(): print(person) else: print("Unknown command")
在第09行上是第一行Py2neo代碼,用來創(chuàng)建了一個(gè)GraphDatabaseService對(duì)象。通過這個(gè),我們就可以訪問使用Neo4j server的大多數(shù)功能??蛇x一個(gè)URI傳遞到這個(gè)構(gòu)造器里,盡管如果什么都沒有提供,代而取之的是使用默認(rèn)的本地參數(shù)。也就是說下面兩行是完全相等的:
graph_db = neo4j.GraphDatabaseService() graph_db = neo4j.GraphDatabaseService ("http://localhost:7474/db/data/")
第13行介紹了調(diào)用了get_or_create_indexed_node,它提供一種在圖形里創(chuàng)建固定引用點(diǎn)的漂亮方式。傳統(tǒng)的Neo4j索引允許節(jié)點(diǎn)和關(guān)系通過鍵值對(duì)訪問,而在這個(gè)代碼里我們使用了帶連接的關(guān)鍵字和root值的引用索引實(shí)例。在第一次執(zhí)行時(shí),會(huì)創(chuàng)建一個(gè)新的節(jié)點(diǎn),而且在隨后的執(zhí)行中,這個(gè)節(jié)點(diǎn)(即root)會(huì)復(fù)用(reused)。
在第17行,我們看見了推薦的節(jié)點(diǎn)和關(guān)系抽象的標(biāo)記,以及接受和使用節(jié)點(diǎn)和關(guān)系抽象的 create方法。任意多的抽象都可以被傳遞到這個(gè)方法中,并且在單個(gè)批處理轉(zhuǎn)換中創(chuàng)建實(shí)體并以指定它們的順序作為一個(gè)列表返回。抽象節(jié)點(diǎn)用 節(jié)點(diǎn)函數(shù)表示并帶有一些屬性,然而抽象關(guān)系使用rel函數(shù)接受一個(gè)起始節(jié)點(diǎn),類型和終止節(jié)點(diǎn)。上下文中,其他節(jié)點(diǎn),關(guān)系起始和終止節(jié)點(diǎn)可能整合引用到在其他批處理中其他節(jié)點(diǎn)。在我們的例子中,我們把根節(jié)點(diǎn)連接到新創(chuàng)建的person節(jié)點(diǎn),否則就作為項(xiàng)目0(item 0)了。
這次我們?cè)诘?4行和38行上以match方法形式和關(guān)系見面[@Lesus 注: oschina代碼行數(shù)有問題。對(duì)應(yīng)于本文的第28和44行]。它試圖使用一個(gè)特殊的條件集合(set)標(biāo)識(shí)關(guān)系,然后使用列表(list)返回它們。這這些示例中,這個(gè)關(guān)系和PERSON關(guān)系相匹配,從root節(jié)點(diǎn)和EMAIL關(guān)系開始到所給定的person節(jié)點(diǎn)。和Cypher很相似,用來查詢包含MATCH關(guān)鍵字的場(chǎng)景。
最后值得注意的一點(diǎn)是在上面的代碼中訪問節(jié)點(diǎn)屬性的方式只是其中一種簡(jiǎn)單的方式。Py2neo重寫了標(biāo)準(zhǔn)python的__getitem__和 __setitem__方法,通過方括號(hào)標(biāo)識(shí)來方便訪問任何屬性。這點(diǎn)在第34和38行上可以看到。[@Lesus 注:對(duì)應(yīng)于本文的第39和44行]
總結(jié)
在那里(代碼行34和38)我們這樣做了,這顯示了它是如何快速簡(jiǎn)易地在JAVA環(huán)境之外拼湊出一個(gè)Neo4j應(yīng)用程序,也顯示了Py2neo是如何通過REST API來抽象出大多數(shù)沉重的負(fù)擔(dān)。這里的例子并沒有解決唯一性,盡管功能上提供了唯一索引和CypherCREATE UNIQUE語句。Django開發(fā)者可能也想要考慮一個(gè)層,如Neomodel,它在Py2neo頂層上表示了一個(gè)Djangoesque ORM-style 層。
相關(guān)文章
詳解Python匿名函數(shù)(lambda函數(shù))
這篇文章主要介紹了Python匿名函數(shù)(lambda函數(shù)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Django框架中間件(Middleware)用法實(shí)例分析
這篇文章主要介紹了Django框架中間件(Middleware)用法,結(jié)合實(shí)例形式分析了Django框架中間件(Middleware)的功能、用法及相關(guān)操作技巧,需要的朋友可以參考下2019-05-05python代碼實(shí)現(xiàn)TSNE降維數(shù)據(jù)可視化教程
今天小編就為大家分享一篇python代碼實(shí)現(xiàn)TSNE降維數(shù)據(jù)可視化教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-02-02基于keras中訓(xùn)練數(shù)據(jù)的幾種方式對(duì)比(fit和fit_generator)
這篇文章主要介紹了keras中訓(xùn)練數(shù)據(jù)的幾種方式對(duì)比(fit和fit_generator),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05詳解Python?Flask?API?示例演示(附cookies和session)
這篇文章主要為大家介紹了Python?Flask?API?示例演示(附cookies和session)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03python3實(shí)現(xiàn)SMTP發(fā)送郵件詳細(xì)教程
這篇文章主要為大家詳細(xì)介紹了python3實(shí)現(xiàn)SMTP發(fā)送郵件的詳細(xì)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06TensorFlow實(shí)現(xiàn)AutoEncoder自編碼器
這篇文章主要為大家詳細(xì)介紹了TensorFlow實(shí)現(xiàn)AutoEncoder自編碼器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03pytorch 實(shí)現(xiàn)在預(yù)訓(xùn)練模型的 input上增減通道
今天小編就為大家分享一篇pytorch 實(shí)現(xiàn)在預(yù)訓(xùn)練模型的 input上增減通道,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01