1. 序章

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

2. 埋め込まれたNeo4j

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

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

<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j</artifactId>
    <version>3.4.6</version>
</dependency>

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

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

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", "baeldung");
owner.setProperty("lastName", "baeldung");

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

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

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

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

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

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

3. Cypherクエリ言語

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

3.1. ノードの作成

Createキーワードは、ノードとリレーションシップの両方を作成するために使用できます。

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

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

3.2. 関係を作成する

1つのクエリで、ノードとそのノードへの関係をすべて作成できます。

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

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

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='Baeldung'" +
  " DELETE company");

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

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

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

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

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

4. Javaドライバー

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

<dependency>
    <groupId>org.neo4j.driver</groupId>
    <artifactId>neo4j-java-driver</artifactId>
    <version>1.6.2</version>
</dependency>

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

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

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

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

Session session = driver.session();

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

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

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

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

5. JDBCドライバー

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

<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-jdbc-driver</artifactId>
    <version>3.4.0</version>
</dependency>

このリンクをたどると、このドライバーの最新バージョンをダウンロードできます。

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

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

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

try (Statement stmt = con.
  stmt.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) "
  + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})"
  + "RETURN baeldung, 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に新しい依存関係を追加します。

<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-ogm-core</artifactId>
    <version>3.1.2</version>
</dependency>

<dependency> 
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-ogm-embedded-driver</artifactId>
    <version>3.1.2</version>
</dependency>

OGM CoreLinkおよびOGMEmbedded 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.baeldung.graph");

最後に、セッションを作成して使用を開始できます。

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

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

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

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

7. 結論

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

いつものように、この記事のコードはすべてGithub利用できます。