Advertisement
techpaste222

Untitled

Jul 7th, 2025
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.16 KB | None | 0 0
  1. import { Database, aql } from "arangojs";
  2.  
  3. // Connect to ArangoDB
  4. const db = new Database({
  5. url: "http://localhost:8529",
  6. databaseName: "unitres",
  7. auth: { username: "root", password: "12345" },
  8. });
  9.  
  10. const edge_weights: Record<string, number> = {
  11. has_email: 5,
  12. has_mobile: 3,
  13. has_device: 2,
  14. has_ip: 1,
  15. };
  16.  
  17. // Clean up: delete all non-system collections (optional, for a fresh start)
  18. async function clear_and_start() {
  19. const collections = await db.listCollections();
  20. for (const coll of collections) {
  21. if (!coll.isSystem) {
  22. await db.collection(coll.name).drop();
  23. }
  24. }
  25.  
  26. // Ensure collections and indexes exist (idempotent)
  27. const vertex = ['person','email','device','mobile','ip'];
  28. const edges = ['has_email','has_device','has_mobile','has_ip'];
  29. for (const name of vertex) {
  30. if (!(await db.collection(name).exists())) {
  31. await db.collection(name).create();
  32. }
  33. }
  34. for (const name of edges) {
  35. if (!(await db.collection(name).exists())) {
  36. await db.collection(name).create({ type: 3 }); // 3 = edge collection
  37. }
  38. }
  39.  
  40. await db.collection('email').ensureIndex({ type: 'persistent', fields: ['email_id', 'disposable'], unique: true });
  41. await db.collection('device').ensureIndex({ type: 'persistent', fields: ['fingerprint'], unique: true });
  42. await db.collection('mobile').ensureIndex({ type: 'persistent', fields: ['mobile_number', 'prepaid', 'imei'], unique: true });
  43. await db.collection('ip').ensureIndex({ type: 'persistent', fields: ['ip_address'], unique: true });
  44. }
  45.  
  46. async function insert(
  47. visitor_id: string,
  48. session_id: string,
  49. lead_id: string,
  50. case_id: string | null,
  51. risk_score: string,
  52. mobile_number: string,
  53. prepaid: number,
  54. imei: string,
  55. email_id: string,
  56. disposable: number,
  57. ip_address: string
  58. ): Promise<string | undefined> {
  59. // Insert person node
  60. const cursor = await db.query(aql`
  61. INSERT {
  62. visitor_id: ${visitor_id},
  63. session_id: ${session_id},
  64. lead_id: ${lead_id},
  65. case_id: ${case_id},
  66. risk_score: ${risk_score}
  67. } INTO person
  68. RETURN NEW._key
  69. `);
  70. const graph_case_id = await cursor.next();
  71.  
  72. const attribute_specs: [string, string, Record<string, any>][] = [
  73. ['email', 'has_email', { email_id, disposable }],
  74. ['device', 'has_device', { fingerprint: session_id }],
  75. ['mobile', 'has_mobile', { mobile_number, prepaid, imei }],
  76. ['ip', 'has_ip', { ip_address }],
  77. ];
  78.  
  79. for (const [coll, edge_coll, attrs] of attribute_specs) {
  80. const attrs_with_key = { ...attrs, _key: graph_case_id };
  81. // Upsert attribute node
  82. const nodeCursor = await db.query(aql`
  83. UPSERT ${attrs}
  84. INSERT ${attrs_with_key}
  85. UPDATE {}
  86. IN ${db.collection(coll)}
  87. RETURN NEW._key
  88. `);
  89. const node_key = await nodeCursor.next();
  90.  
  91. // Insert edge
  92. await db.query(aql`
  93. INSERT {
  94. _from: ${`person/${graph_case_id}`},
  95. _to: ${`${coll}/${node_key}`},
  96. weight: ${edge_weights[edge_coll]}
  97. } INTO ${db.collection(edge_coll)}
  98. `);
  99. }
  100. return graph_case_id;
  101. }
  102.  
  103. async function get_efr(graph_case_id: string): Promise<number | null> {
  104. const cursor = await db.query(aql`
  105. LET avgEfr = AVERAGE(
  106. FOR v, e, p IN 1..10 ANY ${`person/${graph_case_id}`}
  107. has_mobile, has_email, has_ip, has_device
  108. OPTIONS {order: "bfs"}
  109. FILTER v.risk_score == 'P1'
  110. LIMIT 5
  111. LET edgeWeights = p.edges[*].weight
  112. LET totalWeight = SUM(edgeWeights)
  113. LET efrScore = totalWeight / LENGTH(edgeWeights)
  114. RETURN efrScore
  115. )
  116. RETURN MIN([100, ROUND(avgEfr)])
  117. `);
  118. return await cursor.next();
  119. }
  120.  
  121. async function update_caseid_riskscore(graph_case_id: string, case_id: string | number, new_risk_score: string) {
  122. await db.query(aql`
  123. UPDATE ${graph_case_id}
  124. WITH { risk_score: ${new_risk_score}, case_id: ${case_id} }
  125. IN person
  126. `);
  127. }
  128.  
  129. async function get_subgraph(graph_case_id: string, k: number) {
  130. const cursor = await db.query(aql`
  131. FOR v, e, p IN 1..${k} ANY ${`person/${graph_case_id}`}
  132. has_mobile, has_email, has_ip, has_device
  133. OPTIONS {order: "bfs"}
  134. RETURN p
  135. `);
  136. return await cursor.all();
  137. }
  138.  
  139. // --- Example usage ---
  140.  
  141. (async () => {
  142. await clear_and_start();
  143.  
  144. const p1 = await insert('vid1','sid1','lid1', null, 'P1','+919999999999', 1, 'imei123', '[email protected]', 0, '192.168.1.1');
  145. const p2 = await insert('vid2','sid2','lid2', null, 'P2', '+919999999999', 1, 'imei123', '[email protected]', 0, '192.168.1.1');
  146. const p3 = await insert('vid3','sid3','lid3', null, 'P5','+919999999998', 1, 'imei123', '[email protected]', 1, '192.167.1.1');
  147. const p4 = await insert('vid4','sid4','lid4', null, 'P4','+949999999992', 1, 'imei123', '[email protected]', 0, '192.1688.1.1');
  148.  
  149. console.log(p1, p2, p3, p4);
  150. console.log(await get_efr(p1!));
  151. console.log(await get_efr(p2!));
  152. console.log(await get_efr(p3!));
  153. console.log(await get_efr(p4!));
  154.  
  155. await update_caseid_riskscore(p3!, "678", "P1");
  156.  
  157. const subgraph = await get_subgraph(p1!, 6);
  158. if (subgraph.length > 0) {
  159. console.log(subgraph[0]);
  160. }
  161. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement