Skip to content

Commit f423bcd

Browse files
Replace with graphstore check !
Co-authored-by: Veselin Nikolov <[email protected]>
1 parent 6f517e9 commit f423bcd

File tree

8 files changed

+64
-122
lines changed

8 files changed

+64
-122
lines changed
Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,54 +17,64 @@
1717
* You should have received a copy of the GNU General Public License
1818
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1919
*/
20-
package org.neo4j.gds.applications.algorithms.similarity;
20+
package org.neo4j.gds.similarity.filteredknn;
2121

2222
import org.junit.jupiter.api.Test;
23-
import org.neo4j.gds.api.Graph;
24-
import org.neo4j.gds.api.properties.nodes.LongNodePropertyValues;
23+
import org.neo4j.gds.api.GraphStore;
24+
import org.neo4j.gds.similarity.knn.KnnBaseConfig;
2525
import org.neo4j.gds.similarity.knn.KnnNodePropertySpec;
2626

2727
import java.util.List;
2828
import java.util.Set;
2929

3030
import static org.assertj.core.api.Assertions.assertThatThrownBy;
3131
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
32+
import static org.mockito.ArgumentMatchers.anyCollection;
33+
import static org.mockito.ArgumentMatchers.eq;
34+
import static org.mockito.Mockito.doCallRealMethod;
3235
import static org.mockito.Mockito.mock;
3336
import static org.mockito.Mockito.when;
3437

35-
class KnnHookTest {
38+
class KnnBaseConfigTest {
3639

3740
@Test
3841
void shouldNotThrowForExistingProperty(){
39-
var graph = mock(Graph.class);
40-
var nodeProp = mock(LongNodePropertyValues.class);
41-
when(graph.nodeProperties("foo")).thenReturn(nodeProp);
42+
var graphStore = mock(GraphStore.class);
43+
when(graphStore.hasNodeProperty("foo")).thenReturn(true);
4244

4345
var knnSpec = mock(KnnNodePropertySpec.class);
4446
when(knnSpec.name()).thenReturn("foo");
4547

46-
var hook = new KnnHook(List.of(knnSpec));
48+
List<KnnNodePropertySpec> props = List.of(knnSpec);
4749

48-
assertDoesNotThrow( () -> hook.onGraphLoaded(graph));
50+
var config = mock(KnnBaseConfig.class);
51+
when(config.nodeProperties()).thenReturn(props);
52+
53+
doCallRealMethod().when(config).checkPropertiesExist(eq(graphStore),anyCollection(),anyCollection());
54+
55+
assertDoesNotThrow( () -> config.checkPropertiesExist(graphStore,Set.of(),Set.of()));
4956
}
5057

5158
@Test
5259
void shouldThrowForNonExistingProperty(){
53-
var graph = mock(Graph.class);
54-
var nodeProp = mock(LongNodePropertyValues.class);
55-
when(graph.nodeProperties("foo")).thenReturn(nodeProp);
56-
when(graph.nodeProperties("bar")).thenReturn(null);
57-
when(graph.availableNodeProperties()).thenReturn(Set.of("foo"));
60+
var graphStore = mock(GraphStore.class);
61+
when(graphStore.hasNodeProperty("foo")).thenReturn(true);
62+
when(graphStore.hasNodeProperty("bar")).thenReturn(false);
63+
64+
when(graphStore.nodePropertyKeys(anyCollection())).thenReturn(Set.of("foo"));
5865

5966
var knnSpec1 = mock(KnnNodePropertySpec.class);
6067
when(knnSpec1.name()).thenReturn("foo");
6168
var knnSpec2 = mock(KnnNodePropertySpec.class);
6269
when(knnSpec2.name()).thenReturn("bar");
6370

64-
var hook = new KnnHook(List.of(knnSpec1, knnSpec2));
71+
List<KnnNodePropertySpec> props = List.of(knnSpec1, knnSpec2);
6572

66-
assertThatThrownBy(() -> hook.onGraphLoaded(graph))
73+
var config = mock(KnnBaseConfig.class);
74+
when(config.nodeProperties()).thenReturn(props);
75+
doCallRealMethod().when(config).checkPropertiesExist(eq(graphStore),anyCollection(),anyCollection());
76+
77+
assertThatThrownBy(() -> config.checkPropertiesExist(graphStore,Set.of(),Set.of()))
6778
.hasMessageContaining("The property `bar` has not been loaded. Available properties: ['foo']");
6879
}
69-
7080
}

applications/algorithms/similarity/build.gradle

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,10 @@ dependencies {
1414
implementation project(":memory-usage")
1515
implementation project(":progress-tracking")
1616
implementation project(":similarity-configs")
17-
implementation project(':string-formatting')
1817
implementation project(":termination")
1918

2019
// this is needed because NodeSimilarity internally calls Wcc
2120
implementation project(':community-algorithms')
2221
implementation project(":community-configs")
2322

24-
testImplementation project(':test-utils')
25-
2623
}

applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/KnnHook.java

Lines changed: 0 additions & 57 deletions
This file was deleted.

applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsMutateModeBusinessFacade.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@
3333
import org.neo4j.gds.similarity.nodesim.NodeSimilarityMutateConfig;
3434
import org.neo4j.gds.similarity.nodesim.NodeSimilarityResult;
3535

36-
import java.util.List;
3736
import java.util.Map;
38-
import java.util.Optional;
3937

4038
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.FilteredKNN;
4139
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.FilteredNodeSimilarity;
@@ -72,12 +70,9 @@ public <RESULT> RESULT filteredKnn(
7270
shouldComputeSimilarityDistribution
7371
);
7472

75-
return algorithmProcessingTemplateConvenience.processAlgorithmInMutateMode(
76-
Optional.empty(),
73+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInMutateMode(
7774
graphName,
7875
configuration,
79-
Optional.of(List.of(new KnnHook(configuration.nodeProperties()))),
80-
Optional.empty(),
8176
FilteredKNN,
8277
() -> estimationFacade.filteredKnn(configuration),
8378
(graph, __) -> similarityAlgorithms.filteredKnn(graph, configuration),
@@ -121,12 +116,9 @@ public <RESULT> RESULT knn(
121116
shouldComputeSimilarityDistribution
122117
);
123118

124-
return algorithmProcessingTemplateConvenience.processAlgorithmInMutateMode(
125-
Optional.empty(),
119+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInMutateMode(
126120
graphName,
127121
configuration,
128-
Optional.of(List.of(new KnnHook(configuration.nodeProperties()))),
129-
Optional.empty(),
130122
KNN,
131123
() -> estimationFacade.knn(configuration),
132124
(graph, __) -> similarityAlgorithms.knn(graph, configuration),

applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStatsModeBusinessFacade.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@
3030
import org.neo4j.gds.similarity.nodesim.NodeSimilarityResult;
3131
import org.neo4j.gds.similarity.nodesim.NodeSimilarityStatsConfig;
3232

33-
import java.util.List;
34-
import java.util.Optional;
35-
3633
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.FilteredKNN;
3734
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.FilteredNodeSimilarity;
3835
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.KNN;
@@ -58,16 +55,13 @@ public <RESULT> RESULT filteredKnn(
5855
FilteredKnnStatsConfig configuration,
5956
StatsResultBuilder<FilteredKnnResult, RESULT> resultBuilder
6057
) {
61-
return algorithmProcessingTemplateConvenience.processAlgorithmInStatsMode(
58+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInStatsMode(
6259
graphName,
6360
configuration,
6461
FilteredKNN,
6562
() -> estimationFacade.filteredKnn(configuration),
6663
(graph, __) -> similarityAlgorithms.filteredKnn(graph, configuration),
67-
resultBuilder,
68-
Optional.of(List.of(new KnnHook(configuration.nodeProperties()))),
69-
Optional.empty(),
70-
Optional.empty()
64+
resultBuilder
7165
);
7266
}
7367

@@ -91,16 +85,13 @@ public <RESULT> RESULT knn(
9185
KnnStatsConfig configuration,
9286
StatsResultBuilder<KnnResult, RESULT> resultBuilder
9387
) {
94-
return algorithmProcessingTemplateConvenience.processAlgorithmInStatsMode(
88+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInStatsMode(
9589
graphName,
9690
configuration,
9791
KNN,
9892
() -> estimationFacade.knn(configuration),
9993
(graph, __) -> similarityAlgorithms.knn(graph, configuration),
100-
resultBuilder,
101-
Optional.of(List.of(new KnnHook(configuration.nodeProperties()))),
102-
Optional.empty(),
103-
Optional.empty()
94+
resultBuilder
10495
);
10596
}
10697

applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsStreamModeBusinessFacade.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
import org.neo4j.gds.similarity.nodesim.NodeSimilarityResult;
3131
import org.neo4j.gds.similarity.nodesim.NodeSimilarityStreamConfig;
3232

33-
import java.util.List;
34-
import java.util.Optional;
3533
import java.util.stream.Stream;
3634

3735
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.FilteredKNN;
@@ -59,16 +57,13 @@ public <RESULT> Stream<RESULT> filteredKnn(
5957
FilteredKnnStreamConfig configuration,
6058
StreamResultBuilder<FilteredKnnResult, RESULT> resultBuilder
6159
) {
62-
return algorithmProcessingTemplateConvenience.processAlgorithmInStreamMode(
60+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInStreamMode(
6361
graphName,
6462
configuration,
6563
FilteredKNN,
6664
() -> estimationFacade.filteredKnn(configuration),
6765
(graph, __) -> similarityAlgorithms.filteredKnn(graph, configuration),
68-
resultBuilder,
69-
Optional.of(List.of(new KnnHook(configuration.nodeProperties()))),
70-
Optional.empty(),
71-
Optional.empty()
66+
resultBuilder
7267
);
7368
}
7469

@@ -92,16 +87,13 @@ public <RESULT> Stream<RESULT> knn(
9287
KnnStreamConfig configuration,
9388
StreamResultBuilder<KnnResult, RESULT> resultBuilder
9489
) {
95-
return algorithmProcessingTemplateConvenience.processAlgorithmInStreamMode(
90+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInStreamMode(
9691
graphName,
9792
configuration,
9893
KNN,
9994
() -> estimationFacade.knn(configuration),
10095
(graph, __) -> similarityAlgorithms.knn(graph, configuration),
101-
resultBuilder,
102-
Optional.of(List.of(new KnnHook(configuration.nodeProperties()))),
103-
Optional.empty(),
104-
Optional.empty()
96+
resultBuilder
10597
);
10698
}
10799

applications/algorithms/similarity/src/main/java/org/neo4j/gds/applications/algorithms/similarity/SimilarityAlgorithmsWriteModeBusinessFacade.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@
3333
import org.neo4j.gds.similarity.nodesim.NodeSimilarityResult;
3434
import org.neo4j.gds.similarity.nodesim.NodeSimilarityWriteConfig;
3535

36-
import java.util.List;
3736
import java.util.Map;
38-
import java.util.Optional;
3937

4038
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.FilteredKNN;
4139
import static org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel.FilteredNodeSimilarity;
@@ -72,12 +70,9 @@ public <RESULT> RESULT filteredKnn(
7270
writeRelationshipService
7371
);
7472

75-
return algorithmProcessingTemplateConvenience.processAlgorithmInWriteMode(
76-
Optional.empty(),
73+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInWriteMode(
7774
graphName,
7875
configuration,
79-
Optional.of(List.of(new KnnHook(configuration.nodeProperties()))),
80-
Optional.empty(),
8176
FilteredKNN,
8277
() -> estimationFacade.filteredKnn(configuration),
8378
(graph, __) -> similarityAlgorithms.filteredKnn(graph, configuration),
@@ -122,12 +117,9 @@ public <RESULT> RESULT knn(
122117
writeRelationshipService
123118
);
124119

125-
return algorithmProcessingTemplateConvenience.processAlgorithmInWriteMode(
126-
Optional.empty(),
120+
return algorithmProcessingTemplateConvenience.processRegularAlgorithmInWriteMode(
127121
graphName,
128122
configuration,
129-
Optional.of(List.of(new KnnHook(configuration.nodeProperties()))),
130-
Optional.empty(),
131123
KNN,
132124
() -> estimationFacade.knn(configuration),
133125
(graph, __) -> similarityAlgorithms.knn(graph, configuration),

procedures/facade-api/configs/similarity-configs/src/main/java/org/neo4j/gds/similarity/knn/KnnBaseConfig.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,20 @@
1919
*/
2020
package org.neo4j.gds.similarity.knn;
2121

22+
import org.neo4j.gds.NodeLabel;
23+
import org.neo4j.gds.RelationshipType;
2224
import org.neo4j.gds.annotation.Configuration;
25+
import org.neo4j.gds.api.GraphStore;
2326
import org.neo4j.gds.config.AlgoBaseConfig;
2427
import org.neo4j.gds.config.IterationsConfig;
2528
import org.neo4j.gds.config.SingleThreadedRandomSeedConfig;
29+
import org.neo4j.gds.utils.StringJoining;
2630

31+
import java.util.Collection;
2732
import java.util.List;
2833

34+
import static org.neo4j.gds.utils.StringFormatting.formatWithLocale;
35+
2936
@Configuration
3037
public interface KnnBaseConfig extends AlgoBaseConfig, IterationsConfig, SingleThreadedRandomSeedConfig {
3138

@@ -102,4 +109,22 @@ default KnnParametersSansNodeCount toParameters() {
102109
default KnnMemoryEstimationParametersBuilder toMemoryEstimationParameters() {
103110
return new KnnMemoryEstimationParametersBuilder(sampleRate(), topK(), initialSampler());
104111
}
112+
113+
@Configuration.GraphStoreValidationCheck
114+
default void checkPropertiesExist(
115+
GraphStore graphStore,
116+
Collection<NodeLabel> selectedLabels,
117+
Collection<RelationshipType> selectedRelationshipTypes
118+
) {
119+
for (var property : nodeProperties()){
120+
var propertyName = property.name();
121+
if (!graphStore.hasNodeProperty(propertyName)){
122+
throw new IllegalArgumentException(
123+
formatWithLocale("The property `%s` has not been loaded. Available properties: %s",
124+
propertyName,
125+
StringJoining.join(graphStore.nodePropertyKeys(selectedLabels)))
126+
);
127+
}
128+
}
129+
}
105130
}

0 commit comments

Comments
 (0)