クエリの作成
この章では、SDN の抽象化レイヤーを使用する場合のクエリの技術的な作成について説明します。考えられるすべてのケースについて説明するわけではなく、その背後にある一般的な考え方に固執するため、いくつかの簡略化が行われます。
保存
find/load
操作に加えて、save
操作はデータを操作するときに最もよく使用される操作の 1 つです。通常、保存操作呼び出しでは、データベースに対して複数のステートメントを発行して、結果のグラフモデルが指定された Java モデルと一致することを確認します。
ノードの識別子が見つからない場合はノードを作成し、ノード自体が存在する場合はノードのプロパティを更新する Union ステートメントが作成されます。
(
OPTIONAL MATCH (hlp:Person) WHERE id(hlp) = $__id__ WITH hlp WHERE hlp IS NULL CREATE (n:Person) SET n = $__properties__ RETURN id(n) UNION MATCH (n) WHERE id(n) = $__id__ SET n = $__properties__ RETURN id(n)
)エンティティが新しくない場合、ドメインモデルで最初に見つかった型のすべての関連がデータベースから削除されます。
(
MATCH (startNode)-[rel:Has]→(:Hobby) WHERE id(startNode) = $fromId DELETE rel
)関連エンティティはルートエンティティと同じ方法で作成されます。
(
OPTIONAL MATCH (hlp:Hobby) WHERE id(hlp) = $__id__ WITH hlp WHERE hlp IS NULL CREATE (n:Hobby) SET n = $__properties__ RETURN id(n) UNION MATCH (n) WHERE id(n) = $__id__ SET n = $__properties__ RETURN id(n)
)関連そのものが生まれる
(
MATCH (startNode) WHERE id(startNode) = $fromId MATCH (endNode) WHERE id(endNode) = 631 MERGE (startNode)-[:Has]→(endNode)
)関連エンティティが他のエンティティとの関連も持っている場合は、2. と同じ手順が開始されます。
ルートエンティティで次に定義される関連は 2 から始まりますが、first を next に置き換えます。
ご覧のとおり、SDN はグラフモデルと Java の世界の同期を保つために最善を尽くしています。これが、データベースからリレーションシップが削除される可能性があるため、サブグラフのロード、操作、保存を行わないことを強くお勧めする理由の 1 つです。 |
複数のエンティティ
save
操作は、同じ型の複数のエンティティを受け入れる機能でオーバーロードされています。生成された ID 値を使用する場合、またはオプティミスティックロックを使用する場合、すべてのエンティティで個別の CREATE
呼び出しが行われます。
他の場合には、SDN はエンティティ情報を含むパラメーターリストを作成し、MERGE
呼び出しでそれを提供します。
UNWIND $__entities__ AS entity MERGE (n:Person {customId: entity.$__id__}) SET n = entity.__properties__ RETURN collect(n.customId) AS $__ids__
パラメーターは次のようになります
:params {__entities__: [{__id__: 'aa', __properties__: {name: "PersonName", theId: "aa"}}, {__id__ 'bb', __properties__: {name: "AnotherPersonName", theId: "bb"}}]}
ロード
load
ドキュメントでは、クエリの MATCH 部分がどのように見えるかだけでなく、データがどのように返されるかについても説明します。
最も単純なロード操作は findById
呼び出しです。これは、クエリした型のラベルを持つすべてのノードを照合し、ID 値に対してフィルターを実行します。
MATCH (n:Person) WHERE id(n) = 1364
提供されたカスタム ID がある場合、SDN は定義したプロパティを ID として使用します。
MATCH (n:Person) WHERE n.customId = 'anId'
返されるデータは地図射影 (英語) として定義されます。
RETURN n{.first_name, .personNumber, __internalNeo4jId__: id(n), __nodeLabels__: labels(n)}
ご覧のとおり、そこには __internalNeo4jId__
と __nodeLabels__
という 2 つの特別なフィールドがあります。データを Java オブジェクトにマッピングする場合、どちらも重要です。__internalNeo4jId__
の値は id(n)
または指定されたカスタム ID のいずれかですが、マッピングプロセスでは参照する既知のフィールドが 1 つ存在する必要があります。__nodeLabels__
は、このノード上で定義されているラベルをすべて見つけてマッピングできることを保証します。これは、継承が使用され、具象クラスに対してクエリを実行しない場合、またはスーパー型のみを定義する関連が定義されている場合に必要です。
人間関連について話す: エンティティ内でリレーションシップを定義している場合、パターン内包表記 (英語) として返されたマップに追加されます。上記の戻り部分は次のようになります。
RETURN n{.first_name, …, Person_Has_Hobby: [(n)-[:Has]→(n_hobbies:Hobby)|n_hobbies{__internalNeo4jId__: id(n_hobbies), .name, __nodeLabels__: labels(n_hobbies)}]}
SDN で使用されるマップ射影とパターン理解により、定義したプロパティと関連のみがクエリされることが保証されます。
自己参照ノードがある場合、または返されるデータにサイクルが発生する可能性のあるスキーマを作成している場合、SDN はカスケード / データ駆動型のクエリ作成にフォールバックします。特定のノードを検索する最初のクエリから開始して条件を考慮し、結果のノードをステップ順に調べ、それらの関連もマップされている場合は、その場でさらにクエリを作成します。このクエリの作成と実行のループは、クエリで新しい関連やノードが見つからなくなるまで継続します。作成方法は、保存 / 更新プロセスに似ています。