JavaによるNeo4Jの手引き

Javaを使用したNeo4Jのガイド

1. 前書き

この記事はNeo4jについてです。これは、今日の市場で最も成熟したフル機能のグラフデータベースの1つです。 グラフデータベースは、人生の多くのものがnodes(V)のコレクションとして表され、それらの間の接続がedges(E)と呼ばれるという観点から、データモデリングのタスクにアプローチします。

2. 埋め込まれたNeo4j

Neo4jを使い始める最も簡単な方法は、Neo4jがアプリケーションと同じJVMで実行される組み込みバージョンを使用することです。

まず、Maven依存関係を追加する必要があります。


    org.neo4j
    neo4j
    3.4.6

this linkをチェックして、最新バージョンをダウンロードできます。

次に、ファクトリを作成しましょう。

GraphDatabaseFactory graphDbFactory = new GraphDatabaseFactory();

最後に、組み込みデータベースを作成します。

GraphDatabaseService graphDb = graphDbFactory.newEmbeddedDatabase(
  new File("data/cars"));

これで実際のアクションを開始できます! まず、グラフにいくつかのノードを作成する必要があります。そのためには、トランザクションが開始されていない限り、Neo4jが破壊的な操作を拒否するため、トランザクションを開始する必要があります。

graphDb.beginTx();

トランザクションが進行中になったら、ノードの追加を開始できます。

Node car = graphDb.createNode(Label.label("Car"));
car.setProperty("make", "tesla");
car.setProperty("model", "model3");

Node owner = graphDb.createNode(Label.label("Person"));
owner.setProperty("firstName", "example");
owner.setProperty("lastName", "example");

ここでは、プロパティmakemodelを持つノードCarと、プロパティfirstNamelastNameを持つノードPersonを追加しました。

これで、関係を追加できます。

owner.createRelationshipTo(car, RelationshipType.withName("owner"));

上記のステートメントは、2つのノードをownerラベルで結合するエッジを追加しました。 この関係は、Neo4j’sの強力なCypher言語で記述されたクエリを実行することで確認できます。

Result result = graphDb.execute(
  "MATCH (c:Car) <-[owner]- (p:Person) " +
  "WHERE c.make = 'tesla'" +
  "RETURN p.firstName, p.lastName");

ここでは、メーカーがテスラである車の車の所有者を見つけ、firstNameとlastNameを返します。 当然のことながら、これは次を返します:\{p.firstName=example, p.lastName=example}

3. Cypherクエリ言語

Neo4jは、データベースに期待されるすべての機能をサポートする、非常に強力で非常に直感的なクエリ言語を提供します。 標準の作成、取得、更新、削除タスクをどのように達成できるかを調べてみましょう。

3.1. ノードの作成

Createキーワードを使用して、ノードと関係の両方を作成できます。

CREATE (self:Company {name:"example"})
RETURN self

ここでは、単一のプロパティnameを持つ会社を作成しました。 ノード定義は括弧でマークされ、そのプロパティは中括弧で囲まれます。 この場合、selfはノードのエイリアスであり、Companyはノードラベルです。

3.2. 関係を作成する

ノードとそのノードへの関係をすべて単一のクエリで作成することができます。

Result result = graphDb.execute(
  "CREATE (example:Company {name:\"example\"}) " +
  "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
  "RETURN example, tesla");

ここでは、ノードexampleteslaを作成し、それらの間に所有権関係を確立しました。 もちろん、既存のノードとの関係を作成することもできます。

3.3. データを取得する

MATCHキーワードは、RETURNと組み合わせてデータを検索し、返されるデータポイントを制御するために使用されます。 WHERE句を使用して、必要なプロパティを持つノードのみを除外できます。

テスラmodelXを所有している会社の名前を把握しましょう。

Result result = graphDb.execute(
  "MATCH (company:Company)-[:owns]-> (car:Car)" +
  "WHERE car.make='tesla' and car.model='modelX'" +
  "RETURN company.name");

3.4. ノードの更新

SETキーワードは、ノードのプロパティまたはラベルを更新するために使用できます。 テスラにマイルを追加しましょう:

Result result = graphDb.execute("MATCH (car:Car)" +
  "WHERE car.make='tesla'" +
  " SET car.milage=120" +
  " SET car :Car:Electro" +
  " SET car.model=NULL" +
  " RETURN car");

ここでは、milageという新しいプロパティを追加し、ラベルをCarElectroの両方になるように変更し、最後にmodelプロパティを完全に削除します。

3.5. ノードの削除

DELETEキーワードは、グラフからノードまたは関係を永続的に削除するために使用できます。

graphDb.execute("MATCH (company:Company)" +
  " WHERE company.name='example'" +
  " DELETE company");

ここでは、exampleという名前の会社を削除しました。

3.6. パラメータバインディング

上記の例では、ハードコードされたパラメータ値がありますが、これはベストプラクティスではありません。 幸い、Neo4jは、変数をクエリにバインドする機能を提供します。

Map params = new HashMap<>();
params.put("name", "example");
params.put("make", "tesla");
params.put("model", "modelS");

Result result = graphDb.execute("CREATE (example:Company {name:$name}) " +
  "-[:owns]-> (tesla:Car {make: $make, model: $model})" +
  "RETURN example, tesla", params);

4. Javaドライバー

これまで、組み込みのNeo4jインスタンスとのやり取りを検討してきましたが、本番環境では、スタンドアロンサーバーを実行し、提供されているドライバーを介してサーバーに接続する必要があります。 まず、Mavenpom.xmlに別の依存関係を追加する必要があります。


    org.neo4j.driver
    neo4j-java-driver
    1.6.2

this linkをたどって、このドライバーの最新バージョンを確認できます。

これで接続を確立できます。

Driver driver = GraphDatabase.driver(
  "bolt://localhost:7687", AuthTokens.basic("neo4j", "12345"));

次に、セッションを作成します。

Session session = driver.session();

最後に、いくつかのクエリを実行できます。

session.run("CREATE (example:Company {name:\"example\"}) " +
  "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
  "RETURN example, tesla");

すべての作業が完了したら、セッションとドライバーの両方を閉じる必要があります。

session.close();
driver.close();

5. JDBCドライバー

JDBCドライバーを介してNeo4jと対話することもできます。 pom.xmlのさらに別の依存関係:


    org.neo4j
    neo4j-jdbc-driver
    3.4.0

this linkに従って、このドライバーの最新バージョンをダウンロードできます。

次に、JDBC接続を確立しましょう。

Connection con = DriverManager.getConnection(
  "jdbc:neo4j:bolt://localhost/?user=neo4j,password=12345,scheme=basic");

ここで、conは、ステートメントまたはプリペアドステートメントの作成と実行に使用できる通常のJDBC接続です。

try (Statement stmt = con.
  stmt.execute("CREATE (example:Company {name:\"example\"}) "
  + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})"
  + "RETURN example, tesla")

    ResultSet rs = stmt.executeQuery(
      "MATCH (company:Company)-[:owns]-> (car:Car)" +
      "WHERE car.make='tesla' and car.model='modelX'" +
      "RETURN company.name");

    while (rs.next()) {
        rs.getString("company.name");
    }
}

6. オブジェクト-グラフ-マッピング

Object-Graph-MappingまたはOGMは、ドメインPOJOをNeo4jデータベースのエンティティとして使用できるようにする手法です。 これがどのように機能するかを調べてみましょう。 最初のステップは、通常どおり、pom.xmlに新しい依存関係を追加します。


    org.neo4j
    neo4j-ogm-core
    3.1.2



    org.neo4j
    neo4j-ogm-embedded-driver
    3.1.2

OGM Core LinkOGM Embedded Driver Linkをチェックして、これらのライブラリの最新バージョンをチェックできます。

次に、POJOにOGM注釈を付けます。

@NodeEntity
public class Company {
    private Long id;

    private String name;

    @Relationship(type="owns")
    private Car car;
}

@NodeEntity
public class Car {
    private Long id;

    private String make;

    @Relationship(direction = "INCOMING")
    private Company company;
}

@NodeEntityは、このオブジェクトを結果のグラフのノードで表す必要があることをNeo4jに通知します。 @Relationshipは、関連するタイプを表すノードとの関係を作成する必要性を伝えます。 この場合、companycarを所有します。

Neo4jでは、各エンティティに主キーが必要であり、デフォルトでidという名前のフィールドが選択されることに注意してください。 別の名前のフィールドは、@Id @GeneratedValue.で注釈を付けることで使用できます。

次に、Neo4jのOGMをブートストラップするために使用される構成を作成する必要があります。 簡単にするために、組み込みのメモリ内のみのデータベースを使用してみましょう。

Configuration conf = new Configuration.Builder().build();

その後、作成した構成と注釈付きPOJOが存在するパッケージ名でSessionFactoryを初期化します。

SessionFactory factory = new SessionFactory(conf, "com.example.graph");

最後に、Sessionを作成して、使用を開始できます。

Session session = factory.openSession();
Car tesla = new Car("tesla", "modelS");
Company example = new Company("example");

example.setCar(tesla);
session.save(example);

ここで、セッションを開始し、POJOを作成し、OGMセッションにそれらを永続化するように依頼しました。 Neo4j OGMランタイムは、オブジェクトを一連のCypherクエリに透過的に変換し、データベースに適切なノードとエッジを作成しました。

このプロセスがおなじみのように思える場合、それはそうだからです! これがまさにJPAの仕組みです。唯一の違いは、オブジェクトがRDBMSに永続化される行に変換されるか、グラフデータベースに永続化される一連のノードとエッジであるかです。

7. 結論

この記事では、グラフ指向データベースNeo4jのいくつかの基本について説明しました。

いつものように、この記事のコードはすべて利用可能なover on Githubです。