目次
Neo4j の基本
Neo4jとは
Neo4j は、Java に基づいて開発されたオープン ソースの Shcema フリーのグラフ データベースであり、構造化データをテーブルではなくグラフに格納します。これは、完全なトランザクション機能を備えた組み込みのディスクベースの Java 永続化エンジンです。プログラム データは、厳密で静的なテーブルではなく、オブジェクト指向の柔軟なネットワーク構造にありますが、完全にトランザクション対応のエンタープライズ レベル データベースの利点をすべて享受できます。
https://db-engines.com/en/ranking
Neo4j モジュールの構築
Neo4j の主なビルディング ブロック
- ノード
- 属性
- 関係
- ラベル
- データブラウザ
ノード
ノードは、グラフの基本単位です。キーと値のペアを持つプロパティが含まれています
属性
プロパティは、グラフ ノードと関係を記述するために使用されるキーと値のペアです
キー = 値
キーは文字列です
値は、任意の Neo4j データ型を使用して表すことができます
関係
リレーションは、グラフ データベースのもう 1 つの主要な構成要素です。以下に示すように、2 つのノードを接続します。
ここで、Emp と Dept は 2 つの異なるノードです。「WORKS_FOR」は、Emp ノードと Dept ノードの間の関係です。
これは Emp から Dept への矢印マーカーを表しているため、関係は同じことを表しています。
従業員 WORKS_FOR 部門
各関係には、開始ノードと終了ノードが含まれています。
ここで「Emp」は開始ノードです。
「Dept」は終了ノードです。
この関係の矢印は、「Emp」ノードから「Dept」ノードへの関係を表すため、この関係を「Dept」ノードへの「入口関係」と呼びます。
そして、「Emp」ノードへの「外向きの関係」。
ノードと同様に、リレーションシップにもキーと値のペアとして属性を含めることができます。
ラベル
ラベルは、共通名を一連のノードまたは関係に関連付けます。ノードまたは関係には、1 つ以上のラベルを含めることができます。私たちは今できる
ノードまたは関係を持つ新しいタグを作成します。既存のノードまたは関係から既存のラベルを削除できます。
前の図から、2 つのノードがあることがわかります。
左側のノードにはそれぞれラベル「EMP」があり、右側のノードにはラベル「Dept」があります。
これら 2 つのノード間の関係には、「WORKS_FOR」というラベルもあります。
注: - Neo4j は、ノードまたは関係のプロパティにデータを格納します。
Neo4j の主な適用シナリオ
ソーシャルメディアとソーシャルネットワーキング
グラフ データベースを使用してソーシャル ネットワーキング アプリケーションを強化すると、ソーシャル リレーションシップを利用したり、アクティビティに基づいてリレーションシップを推測したりすることが容易になります。
クエリ コミュニティ クラスター分析、友人の友人の推薦、インフルエンサー分析、共有およびコラボレーション関係分析など。
レコメンデーション エンジンと製品レコメンデーション システム
グラフ駆動のレコメンデーション エンジンは、複数の接続をリアルタイムで活用することにより、企業が製品、コンテンツ、およびサービスをパーソナライズするのに役立ちます。
コンテンツとメディアのレコメンデーション、グラフィック支援検索エンジン、製品のレコメンデーション、プロフェッショナル ネットワーキング、ソーシャルのレコメンデーション。
ID およびアクセス管理
ID およびアクセス管理にグラフ データベースを使用すると、ユーザー、資産、関係、承認を迅速かつ効率的に追跡できます。
クエリ アクセス管理、資産の来歴、データの所有権、ID 管理、相互接続された組織、マスター データ、リソースの承認
金融詐欺防止の多次元相関分析シナリオ
グラフ分析により、ユーザーが使用したアカウント番号、IPアドレス、MACアドレス、およびトランザクションが発生したときに携帯電話のIMEI番号に対して相関分析を実行するなど、マネーロンダリングネットワークと関連する疑いを明確に知ることができます.
Neo4j環境構築
Neo4j 環境の Linux でビルドする
(1). Linux に切り替え、インストール ディレクトリ neo4j に移動して、インストール パッケージをアップロードするか、インストール パッケージをダウンロードします。
ftp ツールを使用して、neo4j-community-3.5.17.tar を liunx にアップロードします。
または wget https://neo4j.com/artifact.php?name=neo4j-community-3.5.17-unix.tar.gz
(2).解凍
tar -xvf neo4j-community-3.5.17.tar
(3). 構成ファイル neo4j.conf を変更します。
vi conf/neo4j.conf
主なことは、リモートアクセスを許可するアドレスを変更し、対応するコメントを開くことです
dbms.connectors.default_listen_address=0.0.0.0
(4). 対応するアクセスポートを開き、デフォルトで 7474 と 7687 を開きます
fifirewall-cmd --zone=public --add-port=7474/tcp --permanent
fifirewall-cmd --zone=public --add-port=7687/tcp --permanent
systemctl reload fifirewalld
(5).スタート
./bin/neo4j スタート
(6). ブラウザを使用して、サーバー上の neo4j にアクセスします。
http://192.168.8.128:7474
デフォルトのアカウントは neo4j パスワード neo4j ここで初めてログインすると、パスワードの変更を求められます
ドッカーはNeo4jをインストールします
1. Neo4j イメージをプルする
docker pull neo4j
2. Neo4j を実行するだけ
docker run -d --name neo4j -p 7474:7474 -p 7687:7687 neo4j
3.ログを確認して、起動が成功したかどうかを確認します
docker ログ -f neo4j
4.データブラウザにアクセスして、成功したかどうかを確認します
http://192.168.8.128:7474/ブラウザ
ディレクトリをマウントするには:
- data - データが保存されるフォルダー
- logs - 実行ログ フォルダ
- conf — データベース構成フォルダー (構成ファイル neo4j.conf の構成には、リモート接続の開始と、デフォルトでアクティブ化されたデータベースの設定が含まれます)
- import - csvを大量にインポートしてデータベースを構築するには、インポートが必要なノードファイルnodes.csvと関係ファイルrel.csvをこのフォルダに配置する必要があります)
docker run -d --name container_name \ //-d表示容器后台运行 --name指定容器名字
-p 7474:7474 -p 7687:7687 \ //映射容器的端口号到宿主机的端口号
-v /home/neo4j/data:/data \ //把容器内的数据目录挂载到宿主机的对应目录下
-v /home/neo4j/logs:/logs \ //挂载日志目录
-v /home/neo4j/conf:/var/lib/neo4j/conf //挂载配置目录
-v /home/neo4j/import:/var/lib/neo4j/import \ //挂载数据导入目录
--env NEO4J_AUTH=neo4j/password \ //设定数据库的名字的访问密码
neo4j //指定使用的镜像
Neo4j データ ブラウザ
データブラウザへのアクセス
Neo4j をインストールしたら、次の URL を使用して Neo4j Data Browser にアクセスできます。
http://localhost:7474/browser/
Neo4j Data Browser を使用して、CQL コマンドを実行し、出力を表示します。
ここでは、すべての CQL コマンドをドル プロンプトで実行する必要があります: CREATE(cc:CreditCard) などの「$」、ドル記号の後にコマンドを入力し、[実行] ボタンをクリックしてコマンドを実行します。
Neo4j データベース サーバーとやり取りして、以下の結果を取得し、その $prompt に表示します。
結果をグラフ形式で表示するには、[VI ビュー] ボタンを使用します。上の画像は、結果を「UI ビュー」形式で示しています。
CSV または JSON のエクスポート
[Export CSV] ボタンをクリックして、結果を csv ファイル形式でエクスポートします。
Neo4j CQL
CQLの紹介
CQL は Cypher Query Language の略です。リレーショナル データベースにクエリ言語 SQL があるように、Neo4j はクエリ言語として CQL を使用します。
Neo4j CQL
- Neo4j グラフ データベースのクエリ言語です。
- 宣言型パターンマッチング言語です。
- SQL 構文に従います。
- その構文は非常に単純で、人間が読める形式になっています。
一般的に使用される Neo4j CQL コマンド/用語は次のとおりです。
S.No. |
CQL コマンド/バー |
効果 |
1 | 作成する |
ノード、関係、および属性を作成する |
2 | MATCHマッチ |
ノード、関係、プロパティに関するデータを取得する |
3 | 戻る 戻る |
クエリ結果を返す |
4 | WHERE 条件 |
MATCH データを取得するための条件フィルタリングを提供する |
5 | 削除する |
ノードと関係を削除する |
6 | 削除する |
ノードと関係の属性を削除する |
7 | 設定の設定 |
タグの追加または更新 |
8 | ORDER BY ソート |
結果の並べ替え |
9 | スキップリミットタブ |
ページング |
10 | DISTINCT 重複排除 |
重い放電 |
作成
作成 (
<ノード名>:<ラベル名>
[{
<property1-name>:<property1-Value>
.........
<propertyn-name>:<propertyn-Value>
}]
)
文法の説明:
文法要素 | 説明 |
<ノード名> | 作成するノード名です。 |
<ラベル名> | ノードラベル名です |
<プロパティ1名>...<プロパティn名> |
プロパティはキーと値のペアです。作成されたノードに割り当てられるプロパティの名前を定義します |
<プロパティ1の値>...<プロパティnの値> |
プロパティはキーと値のペアです。作成されたノードのプロパティに割り当てられる値を定義します |
例:
CREATE (person:Person {cid:1,name:"小张",age:24,gender:0,character:"A",money:1000});
MATCH RETURN コマンドの構文
マッチ
(
<ノード名>:<ラベル名>
)
戻る
<ノード名>.<プロパティ1名>,
...
<ノード名>.<プロパティ名>
文法要素 | 説明 |
<ノード名> |
作成するノード名です。 |
<ラベル名> |
ノードラベル名です |
<プロパティ1名>...<プロパティn名> |
プロパティはキーと値のペアです。作成されたノードに割り当てられるプロパティの名前を定義します |
例:
MATCH (人:人) 返す人
MATCH (人:人) return person.name,person.age
関係の創造
- 既存のノードを使用して属性のない関係を作成する
MATCH (<ノード1名>:<ノード1ラベル名>),(<ノード2名>:<ノード2ラベル名>)
作成
(<ノード1名>)-[<関係名>:<関係ラベル名>]->(<ノード2-
名前>)
対応するコンテンツを返す
文法の説明:
S.No. | 文法要素 | 説明 |
1 | マッチ、クリエイト、リターン | これらは Neo4J CQL キーワードです。 |
2 | < node1-name> | 関係の「From ノード」の名前を作成するために使用されます。 |
3 | < node1-label-name> | リレーションシップの「From ノード」のラベル名を作成するために使用されます。 |
4 | < ノード 2 名 > | 関係の「To Node」の名前を作成するために使用されます。 |
5 | < node2-label-name> | リレーションシップの「To Node」のラベル名を作成するために使用されます。 |
6 | <関係名> | これは関係の名前です。 |
7 | <関係ラベル名> | 関係のレーベル名です。 |
例:
関係を作成する
match(person:Person {name:"小张"}) ,(person2:Person {name:"小林"}) create(person)-[r:Couple]->(person2);
クエリ関係
match p = (person:Person {name:"小张"})-[r:Couple]->(person2:Person) return p
match (p1:Person {name:"Xiao Zhang"})-[r:Couple]-(p2:Person) return p1,p2
match (p1:Person {name:"小张"})-[r:Couple]-(p2:Person) return r
- 既存のノードを使用して属性との関係を作成する
MATCH (<node1-label-name>:<node1-name>),(<node2-label-name>:<node2-name>)
作成
(<node1-label-name>)-[<relationship-label-name>:<relationship-name>
{<define-properties-list>}]->(<node2-label-name>)
RETURN <関係ラベル名>
<define-properties-list> は、新しく作成された関係に割り当てるプロパティ (名前と値のペア) のリストです。
{
<property1-name>:<property1-value>,
<property2-name>:<property2-value>,
...
<プロパティ名>:<プロパティ値>
}
例:
match(person:Person {name:"Xiao Zhang"}),(person2:Person {name:"Xiao Lin"})
create(person)-[r:Couple{mary_date:"12/12/2014",price:55000}]->(person2)
rを返します。
- 新しいノードを使用して属性のない関係を作成する
作成
(<node1-label-name>:<node1-name>)
-[<関係ラベル名>:<関係名>]->
(<node1-label-name>:<node1-name>)
例:
作成
(person1:Person {cid:4,name:"小王",age:49,gender:1,character:"A",money:5000})
-[r:フレンド]->
(person2:Person{cid:7,name:"小刘",age:48,gender:0,character:"B",money:100})
- 新しいノードを使用して属性との関係を作成する
作成
(<node1-label-name>:<node1-name>{<define-properties-list>})
-[<関係ラベル名>:<関係名>{<プロパティリストの定義>}]
->(<node1-label-name>:<node1-name>{<define-properties-list>})
例:
作成
(person1:Person {cid:9,name:"王武",age:23,gender:0,character:"A",money:3000})
<-[r:フレンド {date:"11-02-2000"}]->
(person2:Person {cid:8,name:"赵六",age:24,gender:0,character:"B",money:6000})
リレーションシップとノードのプロパティが使用できるタイプ
索引 | CQLデータ型 | 効果 |
1 | ブール値 | ブール値リテラル (true、false) を表すために使用されます。 |
2 | バイト | 8 ビット整数を表すために使用されます。 |
3 | 短い | 16 ビット整数を表すために使用されます。 |
4 | 整数 | 32ビット整数を表すために使用されます |
5 | 長さ | 64 ビット整数を表すために使用されます。 |
6 | 浮く | 浮動小数点数は、32 ビットの浮動小数点数を表すために使用されます。 |
7 | ダブル | Double は、64 ビットの浮動小数点数を表すために使用されます。 |
8 | チャー | Char は、16 ビット文字を表すために使用されます。 |
9 | 弦 | String は、文字列を表すために使用されます。 |
CREATE は複数のタグを作成します
CREATE (<ノード名>:<ラベル名1>:<ラベル名2>.....:<ラベル名>)
好き:
CREATE (person:Person:Beauty:Picture {cid:20,name:"小美女"})
WHERE 子句
简单的WHERE子句
WHERE <condition>
复杂的WHERE子句
WHERE <condition> <boolean-operator> <condition>
where 中的比较运算符 和 之前mysql的相同 如 = != <> > < 等
S.No. | 布尔运算符 | 描述 |
1 | AND | 与 |
2 | OR | 或 |
3 | NOT | 非 |
举例:
MATCH (person:Person)
WHERE person.name = '小张' OR person.name = '小王'
RETURN person
DELETE 子句 和 REMOVE子句
DELETE 子句
- 删除节点。
- 删除节点及相关节点和关系。
match p = (:Person {name:"小王"})-[r:Couple]-(:Person) delete r
REMOVE子句
- 删除节点或关系的标签
- 删除节点或关系的属性
MATCH (person:Person {name:"小美女"}) REMOVE person.cid
SET子句
- 向现有节点或关系添加新属性
- 更新属性值
MATCH (person:Person {cid:1})
SET person.money = 3456,person.age=25
ORDER BY 子句
“ORDER BY”子句,对MATCH查询返回的结果进行排序。
我们可以按升序或降序对行进行排序。
默认情况下,它按升序对行进行排序。 如果我们要按降序对它们进行排序,我们需要使用DESC子句。
MATCH (person:Person)
RETURN person.name,person.money
ORDER BY person.money DESC
SKIP 和 LIMIT
Neo4j CQL已提供“SKIP”子句来过滤或限制查询返回的行数。 它修整了CQL查询结果集顶部的结果。
Neo4j CQL已提供“LIMIT”子句来过滤或限制查询返回的行数。 它修剪CQL查询结果集底部的结果。
MATCH (person:Person)
RETURN ID(person),person.name,person.money
ORDER BY person.money DESC skip 4 limit 2
DISTINCT 排重
这个函数的用法就像SQL中的distinct关键字,返回的是所有不同值。
MATCH (p:Person) RETURN Distinct(p.character)
Neo4j CQL高级
CQL 函数
字符串函数
S.No. | 功能 | 描述 |
1 | UPPER | 它用于将所有字母更改为大写字母。 |
2 | LOWER | 它用于将所有字母改为小写字母。 |
3 | SUBSTRING | 它用于获取给定String的子字符串。 |
4 | REPLACE | 它用于替换一个字符串的子字符串。 |
举例:
MATCH (p:Person)
RETURN ID(p),LOWER(p.character)
match(p:Person) return
p.character,lower(p.character),p.name,substring(p.name,2),replace(p.name,"子","zi")
聚合函数
S.No. | 聚集功能 | 描述 |
1 | COUNT | 它返回由MATCH命令返回的行数。 |
2 | MAX | 它从MATCH命令返回的一组行返回最大值。 |
3 | MIN | 它返回由MATCH命令返回的一组行的最小值。 |
4 | SUM | 它返回由MATCH命令返回的所有行的求和值。 |
5 | AVG | 它返回由MATCH命令返回的所有行的平均值。 |
举例:
MATCH (p:Person)
RETURN MAX(p.money),SUM(p.money)
关系函数
S.No. | 聚集功能 | 描述 |
1 | STARTNODE | 它用于知道关系的开始节点。 |
2 | ENDNODE | 它用于知道关系的结束节点。 |
3 | ID | 它用于知道关系的ID |
4 | TYPE | 它用于知道字符串表示中的一个关系的TYPE。 |
举例:
match p = (:Person {name:"小王"})-[r:Couple]-(:Person)
RETURN STARTNODE(r)
shortestPath 函数返回最短的path
MATCH p=shortestPath( (node1)-[*]-(node2) )
RETURN length(p), nodes(p)
举例:
MATCH p=shortestPath((person:Person {name:"小王"})-[*]-(person2:Person
{name:"王武"}) ) RETURN length(p), nodes(p)
CQL多深度关系节点
使用with关键字
查询三层级关系节点如下:with可以将前面查询结果作为后面查询条件
match (na:Person)-[re]->(nb:Person) where na.name="小张" WITH na,re,nb match (nb:Person)-[re2]->(nc:Person) return na,re,nb,re2,nc
match (na:Person)-[re]->(nb:Person) where na.name="小林" WITH na,re,nb match (nb:Person)-[re2]->(nc:Person) return na,re,nb,re2,nc
直接拼接关系节点查询
match (na:Person{name:"小张"})-[re]->(nb:Person)-[re2]->(nc:Person) return na,re,nb,re2,nc
为了方便,可以将查询结果赋给变量,然后返回
match data=(na:Person{name:"小张"})-[re]->(nb:Person)-[re2]->(nc:Person) return data
使用深度运算符
当实现多深度关系节点查询时,显然使用以上方式比较繁琐。
可变数量的关系->节点可以使用-[:TYPE*minHops..maxHops]-。
查询:
match data=(na:Person{name:"小张"})-[*1..2]-(nb:Person) return data
事务
为了保持数据的完整性和保证良好的事务行为,Neo4j也支持ACID特性 。
注意:
(1)所有对Neo4j数据库的数据修改操作都必须封装在事务里。
(2)默认的isolation level是READ_COMMITTED。
(3)死锁保护已经内置到核心事务管理 。 (Neo4j会在死锁发生之前检测死锁并抛出异常。在异常抛出之前,事务会被标志为回滚。当事务结束时,事务会释放它所持有的锁,则该事务的锁所引起的死锁也就是解除,其他事务就可以继续执行。当用户需要时,抛出异常的事务可以尝试重新执行)
(4)除特别说明,Neo4j的API的操作都是线程安全的,Neo4j数据库的操作也就没有必要使用外部的同步方法。
索引
简介
Neo4j CQL支持节点或关系属性上的索引,以提高应用程序的性能。
可以为具有相同标签名称的属性上创建索引。
可以在MATCH或WHERE等运算符上使用这些索引列来改进CQL 的执行。
创建单一索引
CREATE INDEX ON :Label(property)
例如:
CREATE INDEX ON :Person(name)
创建复合索引
CREATE INDEX ON :Person(age, gender)
全文模式索引
之前的常规模式索引只能对字符串进行精确匹配或者前后缀索(startswith,endswith,contains),全文索引将标记化索引字符串值,因此它可以匹配字符串中任何位置的术语。索引字符串如何被标记化并分解为术语,取决于配置全文模式索引的分析器。索引是通过属性来创建,便于快速查找节点或者关系。
创建和配置全文模式索引
使用db.index.fulltext.createNodeIndex和db.index.fulltext.createRelationshipIndex创建全文模式索引。在创建索引时,每个索引必须为每个索引指定一个唯一的名称,用于在查询或删除索引时引用相关的特定索引。然后,全文模式索引分别应用于标签列表或关系类型列表,分别用于节点和关系索引,然后应用于属性名称列表。
call db.index.fulltext.createNodeIndex("索引名",[Label,Label],[属性,属性])
call db.index.fulltext.createNodeIndex("nameAndDescription",["Person"],["name",
"description"])
call db.index.fulltext.queryNodes("nameAndDescription", "小张") YIELD node, score
RETURN node.name, node.description, score
查看和删除索引
call db.indexes 或者 :schema
DROP INDEX ON :Person(name)
DROP INDEX ON :Person(age, gender)
call db.index.fulltext.drop("nameAndDescription")
约束
唯一性约束
作用
- 避免重复记录。
- 强制执行数据完整性规则
创建唯一性约束
CREATE CONSTRAINT ON (变量:<label_name>) ASSERT 变量.<property_name> IS UNIQUE
具体实例:
CREATE CONSTRAINT ON (person:Person) ASSERT person.name IS UNIQUE
删除唯一性约束
DROP CONSTRAINT ON (cc:Person) ASSERT cc.name IS UNIQUE
3.5.2 属性存在约束 (企业版中可用)
CREATE CONSTRAINT ON (p:Person) ASSERT exists(p.name)
查看约束
call db.constraints
:schema
Neo4j之Admin管理员操作
Neo4j - 数据库备份和恢复
在对Neo4j数据进行备份、还原、迁移的操作时,首先要关闭neo4j
./bin/neo4j stop
数据备份到文件
./bin/neo4j-admin dump --database=graph.db --to=/root/qyn.dump
还原、迁移之前 ,关闭neo4j服务。操作同上
./bin/neo4j-admin load --from=/root/qyn.dump --database=graph.db --force
重启服务
./bin/neo4j start
注意,运行数据备份可能会警告
WARNING: Max 1024 open fifiles allowed, minimum of 40000 recommended. See the Neo4j
manual
1.编辑这个文件
vi /etc/security/limits.conf
在文件最后加入下面这段 修改最大打开文件限制
* soft nofile 65535
* hard nofile 65535
2.重启服务器
再次执行上面的步骤 警告就没有了
调优思路
增加服务器内存 和 调整neo4j配置文件
# java heap 初始值
dbms.memory.heap.initial_size=1g
# java heap 最大值,一般不要超过可用物理内存的80%
dbms.memory.heap.max_size=16g
# pagecache大小,官方建议设为:(总内存-dbms.memory.heap.max_size)/2,
dbms.memory.pagecache.size=2g
neo4j刚启动数据是冷的需要预热
MATCH (n)
OPTIONAL MATCH (n)-[r]->()
RETURN count(n.name) + count(r);
查看执行计划进行索引优化
Cypher查询计划程序将每个查询转换为执行计划。 执行计划告诉Neo4j在执行查询时要执行哪些操作。
对执行计划的生成,Neo4j使用的都是基于成本的优化器(Cost Based Optimizer,CBO),用于制订精确的执行过程。可以采用如下两种不同的方式了解其内部的工作机制:
EXPLAIN:是解释机制,加入该关键字的Cypher语句可以预览执行的过程但并不实际执行,所以也不会产生任何结果。
PROFILE:则是画像机制,查询中使用该关键字,不仅能够看到执行计划的详细内容,也可以看到查询的执行结果。
关注指标:
estimated rows: 需要被扫描行数的预估值
dbhits: 实际运行结果的命中绩效
两个值都是越小越好
使用索引和不使用索引对比
profile MATCH (p { name : '小张' }) RETURN p
在之前加上profile来进行查询,可以查看查询计划
Neo4j 程序访问
SpringBoot 整合Neo4j
1.导入jar包
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zql</groupId>
<artifactId>spring-boot-neo4j-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-neo4j-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.配置文件 application.yml
spring:
data:
neo4j:
username: neo4j
password: neo4j
uri: bolt://localhost:7687
3.建立实体类
@Data
@ToString
public class Person {
@Id
@GeneratedValue
private Long id;
@Property("cid")
private int pid;
@Property
private String name;
private String character;
private double money;
private int gender;
private int age;
private String description;
}
4.数据持久化类
@Repository
public interface PersonRepository extends Neo4jRepository<Person,Long> {
@Query("MATCH (p:Person) where p.money > $money return p")
List<Person> personList(@Param("money")Double money);
@Query("MATCH p=shortestPath((person:Person {name:{0}})-[*1..4]- (person2:Person {name:{1}}) ) RETURN p")
List<Person> shortestPath(String startName,String endName);
}
5.编写服务类
@Service
public class Neo4jPersonService {
@Autowired
private PersonRepository personRepository;
public List<Person> personList(Double money){
return personRepository.personList(money);
}
public List<Person> personAll(){
return personRepository.findAll();
}
public Person save(Person person){
return personRepository.save(person);
}
public List<Person> shortestPath(String startName, String endName){
return personRepository.shortestPath(startName,endName);
}
}
6.编写测试类
@SpringBootTest
class SpringBootNeo4jDemoApplicationTests {
@Autowired
private Neo4jPersonService neo4jPersonService;
/**
* 添加节点
*/
@Test
void save() {
Person person = new Person();
person.setAge(22);
person.setName("小张");
person.setGender(1);
person.setMoney(10000);
person.setGender(1);
person.setDescription("描述");
person.setCharacter("哈哈哈");
person.setPid(2);
Person person1 = neo4jPersonService.save(person);
System.out.println(person1);
}
/**
* 查询所有节点
*/
@Test
void selectAll() {
List<Person> personList = neo4jPersonService.personAll();
System.out.println(personList);
}
/**
* 根据条件查询节点
*/
@Test
void condition() {
List<Person> personList = neo4jPersonService.personList(new Double(1000));
System.out.println(personList);
}
/**
* 最短路径
*/
@Test
void shortestPath() {
List<Person> personList = neo4jPersonService.shortestPath("小张", "王武");
System.out.println(personList);
}
}