查詢建立
本章討論在使用SDN抽象層時查詢的技術建立。會進行一些簡化,因為我們不會討論所有可能的情況,而是堅持其背後的一般思想。
儲存
除了find/load操作,save操作是處理資料時最常用的操作之一。儲存操作呼叫通常會向資料庫發出多個語句,以確保生成的圖模型與給定的Java模型匹配。
-
將建立聯合語句,該語句要麼在找不到節點的識別符號時建立節點,要麼在節點存在時更新節點的屬性。
(
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世界保持同步。這也是我們強烈建議您不要載入、操作和儲存子圖的原因之一,因為這可能會導致關係從資料庫中刪除。 |
多個實體
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__。這兩個欄位在將資料對映到Java物件時都至關重要。__internalNeo4jId__的值是id(n)或提供的自定義id,但在對映過程中必須存在一個已知的引用欄位。__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會回退到級聯/資料驅動的查詢建立。從一個查詢特定節點並考慮條件的初始查詢開始,它遍歷結果節點,如果它們的關係也已對映,則會即時建立進一步的查詢。這個查詢建立和執行迴圈將繼續,直到沒有查詢找到新的關係或節點。建立方式可以類比儲存/更新過程。