generated from amosproj/amos202Xss0Y-projname
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.service.ts
89 lines (78 loc) · 3.08 KB
/
schema.service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { Injectable } from '@nestjs/common';
import { Neo4jService } from 'nest-neo4j/dist';
import { parseNeo4jEntityInfo } from './parseNeo4jEntityInfo';
import { EdgeType, NodeType, NodeTypeConnectionInfo } from '../shared/schema';
import { QueryResult } from '../shared/queries';
import {
SchemaVisualisationResult,
schemaVisualisationToQueryResult,
} from '../utils/schemaVisualisationToQueryResult';
@Injectable()
export class SchemaService {
constructor(private readonly neo4jService: Neo4jService) {}
/**
* Returns information about all edges of a graph
*/
async getEdgeTypes(): Promise<EdgeType[]> {
const result = await this.neo4jService.read(
`CALL db.schema.relTypeProperties`
);
return parseNeo4jEntityInfo(result.records, 'rel');
}
/**
* Returns information about all nodes of a graph
*/
async getNodeTypes(): Promise<NodeType[]> {
const result = await this.neo4jService.read(
`CALL db.schema.nodeTypeProperties`
);
return parseNeo4jEntityInfo(result.records, 'node');
}
/**
* Returns information about the number of connections between node types.
* Nodes with n labels are considered as n nodes of a single label (e.g. node
* :Person:Customer is considered as node :Person and node :Customer).
* This information can be visualized in a Chord diagram.
*/
async getNodeTypeConnectionInformation(): Promise<NodeTypeConnectionInfo[]> {
const result = await this.neo4jService.read(`
CALL db.schema.nodeTypeProperties() YIELD nodeLabels AS result
// flatten ["Person", ["Person", "Customer"]] => ["Person", "Person", "Customer"]
UNWIND result as nodeTypes
// remove duplicates => ["Person", "Customer"]
WITH DISTINCT nodeTypes as nodeTypes
// make List
WITH collect(nodeTypes) as nodeTypes
// build cross product of list => [{from: "Person", to: "Person"}, {from: "Person", to: "Customer"}, ...]
WITH REDUCE(ret = [], A in nodeTypes |
ret + REDUCE(ret2 = [], B in nodeTypes | ret2 + {from: A, to: B})
) as nodeTypes
// each list entry as row
UNWIND nodeTypes as possibleConnections
// get number of connections between nodes
CALL {
WITH possibleConnections
MATCH (a)-->(b)
WHERE possibleConnections['from'] in labels(a) AND possibleConnections['to'] in labels(b)
RETURN count(*)
as numConnections
}
RETURN possibleConnections['from'] as from, possibleConnections['to'] as to, numConnections
`);
return result.records.map((x) => x.toObject() as NodeTypeConnectionInfo);
}
/**
* Returns a {@link QueryResult} containing the meta information about the
* graph, i.e. which node types are connected to which other node types.
*
* The nodes.types always have the length 1.
*/
async getMetaGraph(): Promise<QueryResult> {
const result = await this.neo4jService.read(
`CALL db.schema.visualization()`
);
return schemaVisualisationToQueryResult(
result.records[0].toObject() as SchemaVisualisationResult
);
}
}