37create_relation.mql 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. -- ============================================================================
  2. -- create relation 回归(Cypher: create (a)-[:rel]->(b))
  3. --
  4. -- 覆盖 CreateEdges 的聚合实现:
  5. -- 1) 按 subject 聚合,同一 subject 的所有 relation 合并为一次写;
  6. -- 2) 每个 distinct object 只做一次存在性检查,缺失对象只补插一次;
  7. -- 3) 每个 distinct subject 只做一次存在性检查:存在则一次 PushData(C_Merges 含全部
  8. -- relation),不存在则按带 relation 的方式 insertEntity;
  9. -- 4) relation_stats 按 (inclass, relation, outclass) 三元组去重。
  10. --
  11. -- 存在性检查统一走 omsearch.GetByID(内部经 onesearchproc 按 class 的 core 策略分派)。
  12. -- 注意:该检查不只是"判断存在",它同时会触发 memdb/localdb 后端对该 class 的数据加载;
  13. -- 对 core=memory/local 的类,写入必须先于加载完成之后进行,否则先写入的数据会被随后
  14. -- 的类数据加载覆盖(参见 basic/17cypher/41memdb.mql)。
  15. --
  16. -- 四种组合:
  17. -- 用例1 subject 存在 + object 存在 → 直接 PushData
  18. -- 用例2 subject 存在 + object 不存在 → 先补插 object,再 PushData
  19. -- 用例3 subject 不存在 + object 存在 → insertEntity 创建 subject(带 relation)
  20. -- 用例4 subject 不存在 + object 不存在 → 补插 object + 创建 subject
  21. -- ============================================================================
  22. -- ---------------------------------------------------------------------------
  23. -- 1. 环境准备(可反复执行)
  24. -- ---------------------------------------------------------------------------
  25. -- 先清数据,否则 drop class 会因 "Class ... has data" 失败
  26. delete from /m3graph_crel/node with version
  27. /**
  28. onerror(continue,`not exist`,`not find`,`not found`,`no such`)
  29. **/
  30. ;
  31. drop edge type m3graph_crel.connect
  32. /**
  33. onerror(continue,`not exist`,`not find`,`not found`,`no such`)
  34. **/
  35. ;
  36. drop class if exists /m3graph_crel/node
  37. /**
  38. onerror(continue,`not exist`,`not find`,`not found`,`no such`)
  39. **/
  40. ;
  41. drop class if exists /m3graph_crel
  42. /**
  43. onerror(continue,`not exist`,`not find`,`not found`,`no such`)
  44. **/
  45. ;
  46. /**
  47. sleep(1s)
  48. **/
  49. ;
  50. create class if not exists /m3graph_crel() with core=local, ttl=1 day, namespace='m3graph_crel'
  51. ;
  52. create class if not exists /m3graph_crel/node() with core=local, ttl=1 day, autosearch=true, version=true, nickname='crelnode'
  53. ;
  54. create edge type if not exists m3graph_crel.connect '连接'
  55. ;
  56. /**
  57. sleep(2s)
  58. **/
  59. ;
  60. -- ---------------------------------------------------------------------------
  61. -- 2. 准备已存在的实体
  62. -- s1/o1 → 用例1;s2 → 用例2;o3 → 用例3
  63. -- ---------------------------------------------------------------------------
  64. insert into /m3graph_crel/node id="crelnode:s1"
  65. ;
  66. insert into /m3graph_crel/node id="crelnode:o1"
  67. ;
  68. insert into /m3graph_crel/node id="crelnode:s2"
  69. ;
  70. insert into /m3graph_crel/node id="crelnode:o3"
  71. ;
  72. /**
  73. sleep(1s)
  74. **/
  75. ;
  76. -- ---------------------------------------------------------------------------
  77. -- 3. 四条 create relation,覆盖 subject/object 存在性的四种组合
  78. -- ---------------------------------------------------------------------------
  79. -- 用例1:subject 存在 + object 存在
  80. create ('crelnode:s1')-[:connect]->('crelnode:o1')
  81. ;
  82. -- 用例2:subject 存在 + object 不存在
  83. create ('crelnode:s2')-[:connect]->('crelnode:o2')
  84. ;
  85. -- 用例3:subject 不存在 + object 存在
  86. create ('crelnode:s3')-[:connect]->('crelnode:o3')
  87. ;
  88. -- 用例4:subject 不存在 + object 不存在
  89. create ('crelnode:s4')-[:connect]->('crelnode:o4')
  90. ;
  91. /**
  92. sleep(2s)
  93. **/
  94. ;
  95. -- ---------------------------------------------------------------------------
  96. -- 4. 校验
  97. -- ---------------------------------------------------------------------------
  98. -- 用例1:边建立,两端实体都在
  99. match ('crelnode:s1')-[:connect]->('crelnode:o1')
  100. /**
  101. output()
  102. match("graph.edges.len",1,"graph.nodes.len",2)
  103. **/
  104. ;
  105. -- 用例1:subject 的 connect 记录了 object
  106. select connect from /m3graph_crel/node
  107. /**
  108. output()
  109. matchcount("connect",{"_all":["crelnode:o1"]},1)
  110. **/
  111. ;
  112. -- 用例2:object 被按需补插(CreateEdges 对目标对象做存在性检查并补建)
  113. select id from /m3graph_crel/node where id='crelnode:o2'
  114. /**
  115. output()
  116. count(1)
  117. **/
  118. ;
  119. -- 用例2:subject 的 connect 记录了 object
  120. select connect from /m3graph_crel/node
  121. /**
  122. output()
  123. matchcount("connect",{"_all":["crelnode:o2"]},1)
  124. **/
  125. ;
  126. -- 用例3:subject 被自动创建
  127. select id from /m3graph_crel/node where id='crelnode:s3'
  128. /**
  129. output()
  130. count(1)
  131. **/
  132. ;
  133. -- 用例3:边建立
  134. match ('crelnode:s3')-[:connect]->('crelnode:o3')
  135. /**
  136. output()
  137. match("graph.edges.len",1,"graph.nodes.len",2)
  138. **/
  139. ;
  140. -- 用例3:subject 的 connect 记录了 object
  141. select connect from /m3graph_crel/node
  142. /**
  143. output()
  144. matchcount("connect",{"_all":["crelnode:o3"]},1)
  145. **/
  146. ;
  147. -- 用例4:subject 被自动创建
  148. select id from /m3graph_crel/node where id='crelnode:s4'
  149. /**
  150. output()
  151. count(1)
  152. **/
  153. ;
  154. -- 用例4:object 被自动补插
  155. select id from /m3graph_crel/node where id='crelnode:o4'
  156. /**
  157. output()
  158. count(1)
  159. **/
  160. ;
  161. -- 用例4:边建立
  162. match ('crelnode:s4')-[:connect]->('crelnode:o4')
  163. /**
  164. output()
  165. match("graph.edges.len",1,"graph.nodes.len",2)
  166. **/
  167. ;
  168. -- 用例4:subject 的 connect 记录了 object
  169. select connect from /m3graph_crel/node
  170. /**
  171. output()
  172. matchcount("connect",{"_all":["crelnode:o4"]},1)
  173. **/
  174. ;
  175. -- 四种用例结束后,node 类里应有 8 条记录:s1,o1,s2,o2,s3,o3,s4,o4
  176. select id from /m3graph_crel/node
  177. /**
  178. output()
  179. count(8)
  180. **/
  181. ;