Skip to content

Commit 21f51c7

Browse files
s1ckknutwalker
andcommitted
Project inverse relationships in ScanningRelationshipsImporter
Co-Authored-By: Paul Horn <paul.horn@neotechnology.com>
1 parent 550dd5c commit 21f51c7

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

core/src/main/java/org/neo4j/gds/core/loading/ScanningRelationshipsImporter.java

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,17 @@
2020
package org.neo4j.gds.core.loading;
2121

2222
import org.immutables.builder.Builder;
23+
import org.neo4j.gds.ImmutableRelationshipProjection;
24+
import org.neo4j.gds.RelationshipProjection;
25+
import org.neo4j.gds.RelationshipType;
2326
import org.neo4j.gds.api.GraphLoaderContext;
2427
import org.neo4j.gds.api.IdMap;
2528
import org.neo4j.gds.config.GraphProjectFromStoreConfig;
2629
import org.neo4j.gds.core.GraphDimensions;
2730
import org.neo4j.gds.core.loading.SingleTypeRelationshipImporter.SingleTypeRelationshipImportContext;
2831
import org.neo4j.gds.core.utils.progress.tasks.ProgressTracker;
2932

33+
import java.util.ArrayList;
3034
import java.util.List;
3135
import java.util.stream.Collectors;
3236

@@ -84,12 +88,12 @@ public RecordScannerTaskRunner.RecordScannerTaskFactory recordScannerTaskFactory
8488
ImportSizing sizing,
8589
StoreScanner<RelationshipReference> storeScanner
8690
) {
87-
importContexts = graphProjectConfig
91+
this.importContexts = graphProjectConfig
8892
.relationshipProjections()
8993
.projections()
9094
.entrySet()
9195
.stream()
92-
.map(
96+
.flatMap(
9397
entry -> {
9498
var relationshipType = entry.getKey();
9599
var projection = entry.getValue();
@@ -100,18 +104,26 @@ public RecordScannerTaskRunner.RecordScannerTaskFactory recordScannerTaskFactory
100104
dimensions.relationshipPropertyTokens()
101105
);
102106

103-
var importerFactory = new SingleTypeRelationshipImporterBuilder()
107+
var importer = new SingleTypeRelationshipImporterBuilder()
104108
.importMetaData(importMetaData)
105109
.nodeCountSupplier(dimensions::nodeCount)
106110
.importSizing(sizing)
107111
.validateRelationships(graphProjectConfig.validateRelationships())
108112
.build();
109113

110-
return ImmutableSingleTypeRelationshipImportContext.builder()
114+
var contexts = new ArrayList<SingleTypeRelationshipImportContext>();
115+
116+
contexts.add(ImmutableSingleTypeRelationshipImportContext.builder()
111117
.relationshipType(relationshipType)
112118
.relationshipProjection(projection)
113-
.singleTypeRelationshipImporter(importerFactory)
114-
.build();
119+
.singleTypeRelationshipImporter(importer)
120+
.build());
121+
122+
if (projection.indexInverse()) {
123+
contexts.add(createInverseImporterContext(sizing, relationshipType, projection));
124+
}
125+
126+
return contexts.stream();
115127
}
116128
).collect(Collectors.toList());
117129

@@ -120,13 +132,45 @@ public RecordScannerTaskRunner.RecordScannerTaskFactory recordScannerTaskFactory
120132
progressTracker,
121133
idMap,
122134
storeScanner,
123-
importContexts
135+
this.importContexts
124136
.stream()
125137
.map(SingleTypeRelationshipImportContext::singleTypeRelationshipImporter)
126138
.collect(Collectors.toList())
127139
);
128140
}
129141

142+
private SingleTypeRelationshipImportContext createInverseImporterContext(
143+
ImportSizing sizing,
144+
RelationshipType relationshipType,
145+
RelationshipProjection projection
146+
) {
147+
var inverseProjection = ImmutableRelationshipProjection
148+
.builder()
149+
.from(projection)
150+
.orientation(projection.orientation().inverse())
151+
.build();
152+
153+
var inverseImportMetaData = SingleTypeRelationshipImporter.ImportMetaData.of(
154+
inverseProjection,
155+
dimensions.relationshipTypeTokenMapping().get(relationshipType),
156+
dimensions.relationshipPropertyTokens()
157+
);
158+
159+
var inverseImporter = new SingleTypeRelationshipImporterBuilder()
160+
.importMetaData(inverseImportMetaData)
161+
.nodeCountSupplier(dimensions::nodeCount)
162+
.importSizing(sizing)
163+
.validateRelationships(graphProjectConfig.validateRelationships())
164+
.build();
165+
166+
return ImmutableSingleTypeRelationshipImportContext.builder()
167+
.relationshipType(relationshipType)
168+
.relationshipProjection(inverseProjection)
169+
.inverseOfRelationshipType(relationshipType)
170+
.singleTypeRelationshipImporter(inverseImporter)
171+
.build();
172+
}
173+
130174
@Override
131175
public RelationshipsAndProperties build() {
132176
return RelationshipsAndProperties.of(importContexts);

core/src/main/java/org/neo4j/gds/core/loading/SingleTypeRelationshipImporter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ private static Aggregation[] aggregations(RelationshipProjection projection) {
214214
public interface SingleTypeRelationshipImportContext {
215215
RelationshipType relationshipType();
216216

217+
Optional<RelationshipType> inverseOfRelationshipType();
218+
217219
RelationshipProjection relationshipProjection();
218220

219221
SingleTypeRelationshipImporter singleTypeRelationshipImporter();

0 commit comments

Comments
 (0)