From ba22ba8b87752e61e29ff063afc5752dac0d5e67 Mon Sep 17 00:00:00 2001 From: Linary Date: Fri, 19 Apr 2019 11:58:53 +0800 Subject: [PATCH] Adapt neighborrank and personalrank API (#43) Change-Id: I5f881af79bd514d117e903b9ee823ca87daad82a --- pom.xml | 6 +- .../api/traverser/NeighborRankAPI.java | 202 +++++++ .../api/traverser/PersonalRankAPI.java | 164 ++++++ .../api/traverser/TraversersAPI.java | 6 + .../api/traverser/structure/Ranks.java | 25 + .../baidu/hugegraph/driver/HugeClient.java | 2 +- .../hugegraph/driver/TraverserManager.java | 26 +- .../structure/constant/Traverser.java | 4 + .../hugegraph/version/ClientVersion.java | 2 +- .../com/baidu/hugegraph/api/ApiTestSuite.java | 8 +- .../com/baidu/hugegraph/api/BaseApiTest.java | 6 + .../hugegraph/api/CustomizedPathsApiTest.java | 368 ++++++++++++ .../hugegraph/api/NeighborRankApiTest.java | 411 ++++++++++++++ .../hugegraph/api/PersonalRankApiTest.java | 310 ++++++++++ .../hugegraph/api/ShortestPathApiTest.java | 255 +++++++++ .../baidu/hugegraph/api/TraverserApiTest.java | 532 +----------------- 16 files changed, 1784 insertions(+), 543 deletions(-) create mode 100644 src/main/java/com/baidu/hugegraph/api/traverser/NeighborRankAPI.java create mode 100644 src/main/java/com/baidu/hugegraph/api/traverser/PersonalRankAPI.java create mode 100644 src/main/java/com/baidu/hugegraph/api/traverser/structure/Ranks.java create mode 100644 src/test/java/com/baidu/hugegraph/api/CustomizedPathsApiTest.java create mode 100644 src/test/java/com/baidu/hugegraph/api/NeighborRankApiTest.java create mode 100644 src/test/java/com/baidu/hugegraph/api/PersonalRankApiTest.java create mode 100644 src/test/java/com/baidu/hugegraph/api/ShortestPathApiTest.java diff --git a/pom.xml b/pom.xml index fd14087e7..98743c30f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.baidu.hugegraph hugegraph-client - 1.6.12 + 1.7.0 jar hugegraph-client @@ -53,7 +53,7 @@ UTF-8 1.8 1.8 - 1.5.9 + 1.6.0 2.22 2.8.47 @@ -113,7 +113,7 @@ - 1.6.12.0 + 1.7.0.0 diff --git a/src/main/java/com/baidu/hugegraph/api/traverser/NeighborRankAPI.java b/src/main/java/com/baidu/hugegraph/api/traverser/NeighborRankAPI.java new file mode 100644 index 000000000..4c9f300b8 --- /dev/null +++ b/src/main/java/com/baidu/hugegraph/api/traverser/NeighborRankAPI.java @@ -0,0 +1,202 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.api.traverser; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.baidu.hugegraph.api.traverser.structure.Ranks; +import com.baidu.hugegraph.client.RestClient; +import com.baidu.hugegraph.rest.RestResult; +import com.baidu.hugegraph.structure.constant.Direction; +import com.baidu.hugegraph.structure.constant.Traverser; +import com.baidu.hugegraph.util.E; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class NeighborRankAPI extends TraversersAPI { + + public NeighborRankAPI(RestClient client, String graph) { + super(client, graph); + } + + @Override + protected String type() { + return "neighborrank"; + } + + public List post(Request request) { + RestResult result = this.client.post(this.path(), request); + return result.readList("ranks", Ranks.class); + } + + public static class Request { + + @JsonProperty("source") + private Object source; + @JsonProperty("steps") + private List steps; + @JsonProperty("alpha") + private double alpha; + @JsonProperty("capacity") + private long capacity; + + private Request() { + this.source = null; + this.steps = new ArrayList<>(); + this.alpha = Traverser.DEFAULT_ALPHA; + this.capacity = Traverser.DEFAULT_CAPACITY; + } + + public static Builder builder() { + return new Builder(); + } + + @Override + public String toString() { + return String.format("Request{source=%s,steps=%s,alpha=%s," + + "capacity=%s}", this.source, this.steps, + this.alpha, this.capacity); + } + + public static class Builder { + + private Request request; + private List stepBuilders; + + private Builder() { + this.request = new Request(); + this.stepBuilders = new ArrayList<>(); + } + + public Builder source(Object source) { + E.checkArgument(source != null, "The label of request " + + "for neighbor rank can't be null"); + this.request.source = source; + return this; + } + + public Step.Builder steps() { + Step.Builder builder = new Step.Builder(); + this.stepBuilders.add(builder); + return builder; + } + + public Builder alpha(double alpha) { + TraversersAPI.checkAlpha(alpha); + this.request.alpha = alpha; + return this; + } + + public Builder capacity(long capacity) { + TraversersAPI.checkCapacity(capacity); + this.request.capacity = capacity; + return this; + } + + public Request build() { + for (Step.Builder builder : this.stepBuilders) { + this.request.steps.add(builder.build()); + } + E.checkArgument(this.request.source != null, + "Source vertex can't be null"); + E.checkArgument(this.request.steps != null && + !this.request.steps.isEmpty(), + "Steps can't be null or empty"); + TraversersAPI.checkCapacity(this.request.capacity); + TraversersAPI.checkAlpha(this.request.alpha); + return this.request; + } + } + + public static class Step { + + @JsonProperty("direction") + private String direction; + @JsonProperty("labels") + private List labels; + @JsonProperty("degree") + private long degree; + @JsonProperty("top") + private int top; + + private Step() { + this.direction = null; + this.labels = new ArrayList<>(); + this.degree = Traverser.DEFAULT_DEGREE; + this.top = (int) Traverser.DEFAULT_PATHS_LIMIT; + } + + @Override + public String toString() { + return String.format("Step{direction=%s,labels=%s,degree=%s," + + "top=%s}", this.direction, this.labels, + this.degree, this.top); + } + + public static class Builder { + + private Step step; + + private Builder() { + this.step = new Step(); + } + + public Step.Builder direction(Direction direction) { + this.step.direction = direction.toString(); + return this; + } + + public Step.Builder labels(List labels) { + this.step.labels.addAll(labels); + return this; + } + + public Step.Builder labels(String... labels) { + this.step.labels.addAll(Arrays.asList(labels)); + return this; + } + + public Step.Builder degree(long degree) { + TraversersAPI.checkDegree(degree); + this.step.degree = degree; + return this; + } + + public Step.Builder top(int top) { + E.checkArgument(top > 0 && top <= Traverser.DEFAULT_MAX_TOP, + "The top of each layer cannot exceed %s", + Traverser.DEFAULT_MAX_TOP); + this.step.top = top; + return this; + } + + private Step build() { + TraversersAPI.checkDegree(this.step.degree); + E.checkArgument(this.step.top > 0 && + this.step.top <= Traverser.DEFAULT_MAX_TOP, + "The top of each layer cannot exceed %s", + Traverser.DEFAULT_MAX_TOP); + return this.step; + } + } + } + } +} diff --git a/src/main/java/com/baidu/hugegraph/api/traverser/PersonalRankAPI.java b/src/main/java/com/baidu/hugegraph/api/traverser/PersonalRankAPI.java new file mode 100644 index 000000000..40e38551d --- /dev/null +++ b/src/main/java/com/baidu/hugegraph/api/traverser/PersonalRankAPI.java @@ -0,0 +1,164 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.api.traverser; + +import com.baidu.hugegraph.api.traverser.structure.Ranks; +import com.baidu.hugegraph.client.RestClient; +import com.baidu.hugegraph.rest.RestResult; +import com.baidu.hugegraph.structure.constant.Traverser; +import com.baidu.hugegraph.util.E; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class PersonalRankAPI extends TraversersAPI { + + public PersonalRankAPI(RestClient client, String graph) { + super(client, graph); + } + + @Override + protected String type() { + return "personalrank"; + } + + public Ranks post(Request request) { + RestResult result = this.client.post(this.path(), request); + return result.readObject(Ranks.class); + } + + public static class Request { + + @JsonProperty("source") + private Object source; + @JsonProperty("label") + private String label; + @JsonProperty("alpha") + private double alpha = Traverser.DEFAULT_ALPHA; + @JsonProperty("degree") + public long degree = Traverser.DEFAULT_DEGREE; + @JsonProperty("limit") + private long limit = Traverser.DEFAULT_LIMIT; + @JsonProperty("max_depth") + private int maxDepth = 5; + @JsonProperty("with_label") + private WithLabel withLabel = WithLabel.BOTH_LABEL; + @JsonProperty("sorted") + private boolean sorted = true; + + public static Builder builder() { + return new Builder(); + } + + @Override + public String toString() { + return String.format("Request{source=%s,label=%s,alpha=%s," + + "degree=%s,limit=%s,maxDepth=%s," + + "withLabel=%s,sorted=%s}", + this.source, this.label, this.alpha, + this.degree, this.limit, this.maxDepth, + this.withLabel, this.sorted); + } + + public enum WithLabel { + SAME_LABEL, + OTHER_LABEL, + BOTH_LABEL + } + + public static class Builder { + + private Request request; + + private Builder() { + this.request = new Request(); + } + + public Builder source(Object source) { + E.checkArgument(source != null, "The source of request " + + "for personal rank can't be null"); + this.request.source = source; + return this; + } + + public Builder label(String label) { + E.checkArgument(label != null, "The label of request " + + "for personal rank can't be null"); + this.request.label = label; + return this; + } + + public Builder alpha(double alpha) { + TraversersAPI.checkAlpha(alpha); + this.request.alpha = alpha; + return this; + } + + public Builder degree(long degree) { + TraversersAPI.checkDegree(degree); + this.request.degree = degree; + return this; + } + + public Builder limit(long limit) { + TraversersAPI.checkLimit(limit); + this.request.limit = limit; + return this; + } + + public Builder maxDepth(int maxDepth) { + E.checkArgument(maxDepth > 0 && + maxDepth <= Traverser.DEFAULT_MAX_DEPTH, + "The max depth must be in range (0, %s], " + + "but got: %s", + Traverser.DEFAULT_MAX_DEPTH, maxDepth); + this.request.maxDepth = maxDepth; + return this; + } + + public Builder withLabel(WithLabel withLabel) { + this.request.withLabel = withLabel; + return this; + } + + public Builder sorted(boolean sorted) { + this.request.sorted = sorted; + return this; + } + + public Request build() { + E.checkArgument(this.request.source != null, + "Source vertex can't be null"); + E.checkArgument(this.request.label != null, + "The label of rank request " + + "for personal rank can't be null"); + TraversersAPI.checkAlpha(this.request.alpha); + TraversersAPI.checkDegree(this.request.degree); + TraversersAPI.checkLimit(this.request.limit); + E.checkArgument(this.request.maxDepth > 0 && + this.request.maxDepth <= + Traverser.DEFAULT_MAX_DEPTH, + "The max depth must be in range (0, %s], " + + "but got: %s", + Traverser.DEFAULT_MAX_DEPTH, + this.request.maxDepth); + return this.request; + } + } + } +} diff --git a/src/main/java/com/baidu/hugegraph/api/traverser/TraversersAPI.java b/src/main/java/com/baidu/hugegraph/api/traverser/TraversersAPI.java index 1d963bc9c..e4258c688 100644 --- a/src/main/java/com/baidu/hugegraph/api/traverser/TraversersAPI.java +++ b/src/main/java/com/baidu/hugegraph/api/traverser/TraversersAPI.java @@ -53,4 +53,10 @@ public static void checkCapacity(long capacity) { public static void checkLimit(long limit) { checkLimit(limit, "Limit"); } + + public static void checkAlpha(double alpha) { + E.checkArgument(alpha > 0 && alpha <= 1.0, + "The alpha of rank request must be in range (0, 1], " + + "but got '%s'", alpha); + } } diff --git a/src/main/java/com/baidu/hugegraph/api/traverser/structure/Ranks.java b/src/main/java/com/baidu/hugegraph/api/traverser/structure/Ranks.java new file mode 100644 index 000000000..8be0a341c --- /dev/null +++ b/src/main/java/com/baidu/hugegraph/api/traverser/structure/Ranks.java @@ -0,0 +1,25 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.api.traverser.structure; + +import java.util.LinkedHashMap; + +public class Ranks extends LinkedHashMap { +} diff --git a/src/main/java/com/baidu/hugegraph/driver/HugeClient.java b/src/main/java/com/baidu/hugegraph/driver/HugeClient.java index f01c6c1e6..614f4ac02 100644 --- a/src/main/java/com/baidu/hugegraph/driver/HugeClient.java +++ b/src/main/java/com/baidu/hugegraph/driver/HugeClient.java @@ -118,7 +118,7 @@ private void initManagers(RestClient client, String graph) { private void checkServerApiVersion() { VersionUtil.Version apiVersion = VersionUtil.Version.of( this.version.getApiVersion()); - VersionUtil.check(apiVersion, "0.37", "0.38", + VersionUtil.check(apiVersion, "0.38", "0.39", "hugegraph-api in server"); } diff --git a/src/main/java/com/baidu/hugegraph/driver/TraverserManager.java b/src/main/java/com/baidu/hugegraph/driver/TraverserManager.java index c9bcd90b5..995f86197 100644 --- a/src/main/java/com/baidu/hugegraph/driver/TraverserManager.java +++ b/src/main/java/com/baidu/hugegraph/driver/TraverserManager.java @@ -19,6 +19,11 @@ package com.baidu.hugegraph.driver; +import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_CAPACITY; +import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_DEGREE; +import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_ELEMENTS_LIMIT; +import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_PAGE_LIMIT; + import java.util.List; import com.baidu.hugegraph.api.traverser.CrosspointsAPI; @@ -27,7 +32,9 @@ import com.baidu.hugegraph.api.traverser.EdgesAPI; import com.baidu.hugegraph.api.traverser.KneighborAPI; import com.baidu.hugegraph.api.traverser.KoutAPI; +import com.baidu.hugegraph.api.traverser.NeighborRankAPI; import com.baidu.hugegraph.api.traverser.PathsAPI; +import com.baidu.hugegraph.api.traverser.PersonalRankAPI; import com.baidu.hugegraph.api.traverser.RaysAPI; import com.baidu.hugegraph.api.traverser.RingsAPI; import com.baidu.hugegraph.api.traverser.ShortestPathAPI; @@ -36,6 +43,7 @@ import com.baidu.hugegraph.api.traverser.structure.CustomizedCrosspoints; import com.baidu.hugegraph.api.traverser.structure.CustomizedPaths; import com.baidu.hugegraph.api.traverser.structure.PathsRequest; +import com.baidu.hugegraph.api.traverser.structure.Ranks; import com.baidu.hugegraph.client.RestClient; import com.baidu.hugegraph.structure.constant.Direction; import com.baidu.hugegraph.structure.graph.Edge; @@ -46,12 +54,6 @@ import com.baidu.hugegraph.structure.graph.Vertices; import com.baidu.hugegraph.util.E; -import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_PAGE_LIMIT; - -import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_CAPACITY; -import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_DEGREE; -import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_ELEMENTS_LIMIT; - public class TraverserManager { private final GraphManager graphManager; @@ -65,6 +67,8 @@ public class TraverserManager { private RaysAPI raysAPI; private CustomizedPathsAPI customizedPathsAPI; private CustomizedCrosspointsAPI customizedCrosspointsAPI; + private NeighborRankAPI neighborRankAPI; + private PersonalRankAPI personalRankAPI; private VerticesAPI verticesAPI; private EdgesAPI edgesAPI; @@ -81,6 +85,8 @@ public TraverserManager(RestClient client, GraphManager graphManager) { this.customizedPathsAPI = new CustomizedPathsAPI(client, graph); this.customizedCrosspointsAPI = new CustomizedCrosspointsAPI(client, graph); + this.neighborRankAPI = new NeighborRankAPI(client, graph); + this.personalRankAPI = new PersonalRankAPI(client, graph); this.verticesAPI = new VerticesAPI(client, graph); this.edgesAPI = new EdgesAPI(client, graph); } @@ -209,6 +215,14 @@ public CustomizedCrosspoints customizedCrosspointss( return this.customizedCrosspointsAPI.post(request); } + public List neighborRank(NeighborRankAPI.Request request) { + return this.neighborRankAPI.post(request); + } + + public Ranks personalRank(PersonalRankAPI.Request request) { + return this.personalRankAPI.post(request); + } + public List vertexShards(long splitSize) { return this.verticesAPI.shards(splitSize); } diff --git a/src/main/java/com/baidu/hugegraph/structure/constant/Traverser.java b/src/main/java/com/baidu/hugegraph/structure/constant/Traverser.java index 91fb186bb..3f2e2c49a 100644 --- a/src/main/java/com/baidu/hugegraph/structure/constant/Traverser.java +++ b/src/main/java/com/baidu/hugegraph/structure/constant/Traverser.java @@ -22,6 +22,7 @@ public class Traverser { public static final long DEFAULT_CAPACITY = 10_000_000L; + public static final long DEFAULT_LIMIT = 100L; public static final long DEFAULT_ELEMENTS_LIMIT = 10_000_000L; public static final long DEFAULT_DEGREE = 10_000L; public static final long DEFAULT_CROSSPOINT_LIMIT = 10_000L; @@ -29,4 +30,7 @@ public class Traverser { public static final long DEFAULT_SAMPLE = 100L; public static final double DEFAULT_WEIGHT = 0.0D; public static final long DEFAULT_PAGE_LIMIT = 100_000L; + public static final double DEFAULT_ALPHA = 0.9; + public static final int DEFAULT_MAX_TOP = 1000; + public static final int DEFAULT_MAX_DEPTH = 50; } diff --git a/src/main/java/com/baidu/hugegraph/version/ClientVersion.java b/src/main/java/com/baidu/hugegraph/version/ClientVersion.java index 41ced5475..e8769958d 100644 --- a/src/main/java/com/baidu/hugegraph/version/ClientVersion.java +++ b/src/main/java/com/baidu/hugegraph/version/ClientVersion.java @@ -35,7 +35,7 @@ public class ClientVersion { public static final void check() { // Check version of hugegraph-common - VersionUtil.check(CommonVersion.VERSION, "1.5", "1.6", + VersionUtil.check(CommonVersion.VERSION, "1.6", "1.7", CommonVersion.NAME); } } diff --git a/src/test/java/com/baidu/hugegraph/api/ApiTestSuite.java b/src/test/java/com/baidu/hugegraph/api/ApiTestSuite.java index aa845a75f..49eefff24 100644 --- a/src/test/java/com/baidu/hugegraph/api/ApiTestSuite.java +++ b/src/test/java/com/baidu/hugegraph/api/ApiTestSuite.java @@ -32,10 +32,14 @@ EdgeApiTest.class, GremlinApiTest.class, VariablesApiTest.class, - TraverserApiTest.class, TaskApiTest.class, JobApiTest.class, - RestoreApiTest.class + RestoreApiTest.class, + TraverserApiTest.class, + ShortestPathApiTest.class, + CustomizedPathsApiTest.class, + NeighborRankApiTest.class, + PersonalRankApiTest.class }) public class ApiTestSuite { } diff --git a/src/test/java/com/baidu/hugegraph/api/BaseApiTest.java b/src/test/java/com/baidu/hugegraph/api/BaseApiTest.java index 8bca42908..9aeb7bf19 100644 --- a/src/test/java/com/baidu/hugegraph/api/BaseApiTest.java +++ b/src/test/java/com/baidu/hugegraph/api/BaseApiTest.java @@ -41,7 +41,9 @@ import com.baidu.hugegraph.api.traverser.EdgesAPI; import com.baidu.hugegraph.api.traverser.KneighborAPI; import com.baidu.hugegraph.api.traverser.KoutAPI; +import com.baidu.hugegraph.api.traverser.NeighborRankAPI; import com.baidu.hugegraph.api.traverser.PathsAPI; +import com.baidu.hugegraph.api.traverser.PersonalRankAPI; import com.baidu.hugegraph.api.traverser.RaysAPI; import com.baidu.hugegraph.api.traverser.RingsAPI; import com.baidu.hugegraph.api.traverser.ShortestPathAPI; @@ -70,6 +72,8 @@ public class BaseApiTest extends BaseClientTest { protected static RaysAPI raysAPI; protected static CustomizedPathsAPI customizedPathsAPI; protected static CustomizedCrosspointsAPI customizedCrosspointsAPI; + protected static NeighborRankAPI neighborRankAPI; + protected static PersonalRankAPI personalRankAPI; protected static VerticesAPI verticesAPI; protected static EdgesAPI edgesAPI; protected static TaskAPI taskAPI; @@ -97,6 +101,8 @@ public static void init() { raysAPI = new RaysAPI(client, GRAPH); customizedPathsAPI = new CustomizedPathsAPI(client, GRAPH); customizedCrosspointsAPI = new CustomizedCrosspointsAPI(client, GRAPH); + neighborRankAPI = new NeighborRankAPI(client, GRAPH); + personalRankAPI = new PersonalRankAPI(client, GRAPH); verticesAPI = new VerticesAPI(client, GRAPH); edgesAPI = new EdgesAPI(client, GRAPH); taskAPI = new TaskAPI(client, GRAPH); diff --git a/src/test/java/com/baidu/hugegraph/api/CustomizedPathsApiTest.java b/src/test/java/com/baidu/hugegraph/api/CustomizedPathsApiTest.java new file mode 100644 index 000000000..95f380074 --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/api/CustomizedPathsApiTest.java @@ -0,0 +1,368 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.api; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.baidu.hugegraph.api.traverser.structure.CustomizedPaths; +import com.baidu.hugegraph.api.traverser.structure.PathsRequest; +import com.baidu.hugegraph.driver.SchemaManager; +import com.baidu.hugegraph.exception.ServerException; +import com.baidu.hugegraph.structure.constant.Direction; +import com.baidu.hugegraph.structure.graph.Vertex; +import com.baidu.hugegraph.structure.schema.EdgeLabel; +import com.baidu.hugegraph.testutil.Assert; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +public class CustomizedPathsApiTest extends BaseApiTest { + + @BeforeClass + public static void prepareSchemaAndGraph() { + BaseApiTest.initPropertyKey(); + BaseApiTest.initVertexLabel(); + BaseApiTest.initVertex(); + } + + @Before + public void setup() { + initEdgesWithWeights(); + } + + @After + public void teardown() { + removeEdgesWithWeights(); + } + + @Test + public void testCustomizedPathsSourceLabelProperty() { + Object markoId = getVertexId("person", "name", "marko"); + Object joshId = getVertexId("person", "name", "josh"); + Object rippleId = getVertexId("software", "name", "ripple"); + Object lopId = getVertexId("software", "name", "lop"); + + PathsRequest.Builder builder = new PathsRequest.Builder(); + builder.sources().label("person").property("name", "marko"); + builder.steps().direction(Direction.OUT).labels("knows1") + .weightBy("weight").degree(-1); + builder.steps().direction(Direction.OUT).labels("created1") + .weightBy("weight").degree(-1); + builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) + .capacity(-1).limit(-1); + PathsRequest request = builder.build(); + + CustomizedPaths customizedPaths = customizedPathsAPI.post(request); + List paths = customizedPaths.paths(); + + Assert.assertEquals(2, paths.size()); + + List path1 = ImmutableList.of(markoId, joshId, lopId); + List path2 = ImmutableList.of(markoId, joshId, rippleId); + Assert.assertEquals(path1, paths.get(0).objects()); + Assert.assertEquals(path2, paths.get(1).objects()); + + List weights1 = ImmutableList.of(1.0D, 0.4D); + List weights2 = ImmutableList.of(1.0D, 1.0D); + Assert.assertEquals(weights1, paths.get(0).weights()); + Assert.assertEquals(weights2, paths.get(1).weights()); + + Set vertices = customizedPaths.vertices().stream() + .map(Vertex::id) + .collect(Collectors.toSet()); + Assert.assertEquals(4, vertices.size()); + Set expectedVertices = ImmutableSet.of(markoId, lopId, + rippleId, joshId); + Assert.assertEquals(expectedVertices, vertices); + } + + @Test + public void testCustomizedPathsSourceIds() { + Object markoId = getVertexId("person", "name", "marko"); + Object lopId = getVertexId("software", "name", "lop"); + Object peterId = getVertexId("person", "name", "peter"); + + PathsRequest.Builder builder = new PathsRequest.Builder(); + builder.sources().ids(markoId, peterId); + builder.steps().direction(Direction.OUT).labels("created1") + .weightBy("weight").degree(-1); + builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) + .capacity(-1).limit(-1); + PathsRequest request = builder.build(); + + CustomizedPaths customizedPaths = customizedPathsAPI.post(request); + List paths = customizedPaths.paths(); + + Assert.assertEquals(2, paths.size()); + + List path1 = ImmutableList.of(markoId, lopId); + List path2 = ImmutableList.of(peterId, lopId); + List> expectedPaths = ImmutableList.of(path1, path2); + Assert.assertTrue(expectedPaths.contains(paths.get(0).objects())); + Assert.assertTrue(expectedPaths.contains(paths.get(1).objects())); + + List weights1 = ImmutableList.of(0.2D); + List weights2 = ImmutableList.of(0.4D); + List> expectedWeights = ImmutableList.of(weights1, + weights2); + Assert.assertTrue(expectedWeights.contains(paths.get(0).weights())); + Assert.assertTrue(expectedWeights.contains(paths.get(1).weights())); + + Set vertices = customizedPaths.vertices().stream() + .map(Vertex::id) + .collect(Collectors.toSet()); + Assert.assertEquals(3, vertices.size()); + Set expectedVertices = ImmutableSet.of(markoId, lopId, peterId); + Assert.assertEquals(expectedVertices, vertices); + } + + @Test + public void testCustomizedPathsSourceLabelPropertyMultiValue() { + Object markoId = getVertexId("person", "name", "marko"); + Object lopId = getVertexId("software", "name", "lop"); + Object peterId = getVertexId("person", "name", "peter"); + + PathsRequest.Builder builder = new PathsRequest.Builder(); + List names = ImmutableList.of("marko", "peter"); + builder.sources().label("person").property("name", names); + builder.steps().direction(Direction.OUT).labels("created1") + .weightBy("weight").degree(-1); + builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) + .capacity(-1).limit(-1); + PathsRequest request = builder.build(); + + CustomizedPaths customizedPaths = customizedPathsAPI.post(request); + List paths = customizedPaths.paths(); + + Assert.assertEquals(2, paths.size()); + + List path1 = ImmutableList.of(markoId, lopId); + List path2 = ImmutableList.of(peterId, lopId); + List> expectedPaths = ImmutableList.of(path1, path2); + Assert.assertTrue(expectedPaths.contains(paths.get(0).objects())); + Assert.assertTrue(expectedPaths.contains(paths.get(1).objects())); + + List weights1 = ImmutableList.of(0.2D); + List weights2 = ImmutableList.of(0.4D); + List> expectedWeights = ImmutableList.of(weights1, + weights2); + Assert.assertTrue(expectedWeights.contains(paths.get(0).weights())); + Assert.assertTrue(expectedWeights.contains(paths.get(1).weights())); + + Set vertices = customizedPaths.vertices().stream() + .map(Vertex::id) + .collect(Collectors.toSet()); + Assert.assertEquals(3, vertices.size()); + Set expectedVertices = ImmutableSet.of(markoId, lopId, peterId); + Assert.assertEquals(expectedVertices, vertices); + } + + @Test + public void testCustomizedPathsWithSample() { + Object markoId = getVertexId("person", "name", "marko"); + Object joshId = getVertexId("person", "name", "josh"); + Object rippleId = getVertexId("software", "name", "ripple"); + Object lopId = getVertexId("software", "name", "lop"); + + PathsRequest.Builder builder = new PathsRequest.Builder(); + builder.sources().label("person").property("name", "marko"); + builder.steps().direction(Direction.OUT).labels("knows1") + .weightBy("weight").degree(-1); + builder.steps().direction(Direction.OUT).labels("created1") + .weightBy("weight").degree(-1).sample(1); + builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) + .capacity(-1).limit(-1); + PathsRequest request = builder.build(); + + CustomizedPaths customizedPaths = customizedPathsAPI.post(request); + List paths = customizedPaths.paths(); + + Assert.assertEquals(1, paths.size()); + + List path1 = ImmutableList.of(markoId, joshId, rippleId); + List path2 = ImmutableList.of(markoId, joshId, lopId); + List> expectedPaths = ImmutableList.of(path1, path2); + Assert.assertTrue(expectedPaths.contains(paths.get(0).objects())); + + List weights1 = ImmutableList.of(1D, 0.4D); + List weights2 = ImmutableList.of(1D, 1D); + + Assert.assertTrue(weights1.equals(paths.get(0).weights()) || + weights2.equals(paths.get(0).weights())); + + Set vertices = customizedPaths.vertices().stream() + .map(Vertex::id) + .collect(Collectors.toSet()); + Assert.assertEquals(3, vertices.size()); + Assert.assertTrue(path1.containsAll(vertices) || + path2.containsAll(vertices)); + } + + @Test + public void testCustomizedPathsWithDecr() { + Object markoId = getVertexId("person", "name", "marko"); + Object joshId = getVertexId("person", "name", "josh"); + Object rippleId = getVertexId("software", "name", "ripple"); + Object lopId = getVertexId("software", "name", "lop"); + + PathsRequest.Builder builder = new PathsRequest.Builder(); + builder.sources().label("person").property("name", "marko"); + builder.steps().direction(Direction.OUT).labels("knows1") + .weightBy("weight").degree(-1); + builder.steps().direction(Direction.OUT).labels("created1") + .weightBy("weight").degree(-1); + builder.sortBy(PathsRequest.SortBy.DECR).withVertex(true) + .capacity(-1).limit(-1); + PathsRequest request = builder.build(); + + CustomizedPaths customizedPaths = customizedPathsAPI.post(request); + List paths = customizedPaths.paths(); + + Assert.assertEquals(2, paths.size()); + + List path1 = ImmutableList.of(markoId, joshId, rippleId); + List path2 = ImmutableList.of(markoId, joshId, lopId); + Assert.assertEquals(path1, paths.get(0).objects()); + Assert.assertEquals(path2, paths.get(1).objects()); + + List weights1 = ImmutableList.of(1.0D, 1.0D); + List weights2 = ImmutableList.of(1.0D, 0.4D); + Assert.assertEquals(weights1, paths.get(0).weights()); + Assert.assertEquals(weights2, paths.get(1).weights()); + + Set vertices = customizedPaths.vertices().stream() + .map(Vertex::id) + .collect(Collectors.toSet()); + Assert.assertEquals(4, vertices.size()); + Set expectedVertices = ImmutableSet.of(markoId, lopId, + rippleId, joshId); + Assert.assertEquals(expectedVertices, vertices); + } + + @Test + public void testCustomizedPathsWithLimit() { + Object markoId = getVertexId("person", "name", "marko"); + Object joshId = getVertexId("person", "name", "josh"); + Object rippleId = getVertexId("software", "name", "ripple"); + Object lopId = getVertexId("software", "name", "lop"); + + PathsRequest.Builder builder = new PathsRequest.Builder(); + builder.sources().label("person").property("name", "marko"); + builder.steps().direction(Direction.OUT).labels("knows1") + .weightBy("weight").degree(-1); + builder.steps().direction(Direction.OUT).labels("created1") + .weightBy("weight").degree(-1); + builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) + .capacity(-1).limit(1); + PathsRequest request = builder.build(); + + CustomizedPaths customizedPaths = customizedPathsAPI.post(request); + List paths = customizedPaths.paths(); + + Assert.assertEquals(1, paths.size()); + + List path1 = ImmutableList.of(markoId, joshId, lopId); + List path2 = ImmutableList.of(markoId, joshId, rippleId); + List> expectedPaths = ImmutableList.of(path1, path2); + Assert.assertTrue(expectedPaths.contains(paths.get(0).objects())); + + List weights1 = ImmutableList.of(1.0D, 0.4D); + List weights2 = ImmutableList.of(1.0D, 1.0D); + List> expectedWeights = ImmutableList.of(weights1, + weights2); + Assert.assertTrue(expectedWeights.contains(paths.get(0).weights())); + + Set vertices = customizedPaths.vertices().stream() + .map(Vertex::id) + .collect(Collectors.toSet()); + Assert.assertEquals(3, vertices.size()); + Set vertices1 = ImmutableSet.of(markoId, lopId, joshId); + Set vertices2 = ImmutableSet.of(markoId, lopId, rippleId); + Set> expectedVertices = ImmutableSet.of(vertices1, vertices2); + Assert.assertTrue(expectedVertices.contains(vertices)); + } + + @Test + public void testCustomizedPathsWithCapacity() { + PathsRequest.Builder builder = new PathsRequest.Builder(); + builder.sources().label("person").property("name", "marko"); + builder.steps().direction(Direction.OUT).labels("knows1") + .weightBy("weight").degree(-1); + builder.steps().direction(Direction.OUT).labels("created1") + .weightBy("weight").degree(-1); + builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) + .capacity(1).limit(-1); + PathsRequest request = builder.build(); + + Assert.assertThrows(ServerException.class, () -> { + customizedPathsAPI.post(request); + }); + } + + private static void initEdgesWithWeights() { + SchemaManager schema = schema(); + schema.edgeLabel("knows1") + .sourceLabel("person") + .targetLabel("person") + .properties("date", "weight") + .nullableKeys("weight") + .ifNotExist() + .create(); + + schema.edgeLabel("created1") + .sourceLabel("person") + .targetLabel("software") + .properties("date", "weight") + .nullableKeys("weight") + .ifNotExist() + .create(); + + Vertex marko = getVertex("person", "name", "marko"); + Vertex vadas = getVertex("person", "name", "vadas"); + Vertex lop = getVertex("software", "name", "lop"); + Vertex josh = getVertex("person", "name", "josh"); + Vertex ripple = getVertex("software", "name", "ripple"); + Vertex peter = getVertex("person", "name", "peter"); + + marko.addEdge("knows1", vadas, "date", "20160110", "weight", 0.5); + marko.addEdge("knows1", josh, "date", "20130220", "weight", 1.0); + marko.addEdge("created1", lop, "date", "20171210", "weight", 0.4); + josh.addEdge("created1", lop, "date", "20091111", "weight", 0.4); + josh.addEdge("created1", ripple, "date", "20171210", "weight", 1.0); + peter.addEdge("created1", lop, "date", "20170324", "weight", 0.2); + } + + private static void removeEdgesWithWeights() { + List elTaskIds = new ArrayList<>(); + EdgeLabel knows1 = schema().getEdgeLabel("knows1"); + EdgeLabel created1 = schema().getEdgeLabel("created1"); + ImmutableList.of(knows1, created1).forEach(edgeLabel -> { + elTaskIds.add(edgeLabelAPI.delete(edgeLabel.name())); + }); + elTaskIds.forEach(BaseApiTest::waitUntilTaskCompleted); + } +} diff --git a/src/test/java/com/baidu/hugegraph/api/NeighborRankApiTest.java b/src/test/java/com/baidu/hugegraph/api/NeighborRankApiTest.java new file mode 100644 index 000000000..69a010997 --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/api/NeighborRankApiTest.java @@ -0,0 +1,411 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.api; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.baidu.hugegraph.api.traverser.NeighborRankAPI; +import com.baidu.hugegraph.api.traverser.structure.Ranks; +import com.baidu.hugegraph.driver.GraphManager; +import com.baidu.hugegraph.driver.SchemaManager; +import com.baidu.hugegraph.exception.ServerException; +import com.baidu.hugegraph.structure.constant.Direction; +import com.baidu.hugegraph.structure.constant.T; +import com.baidu.hugegraph.structure.graph.Vertex; +import com.baidu.hugegraph.testutil.Assert; +import com.google.common.collect.ImmutableMap; + +public class NeighborRankApiTest extends BaseApiTest { + + @BeforeClass + public static void initNeighborRankGraph() { + GraphManager graph = graph(); + SchemaManager schema = schema(); + + schema.propertyKey("name").asText().ifNotExist().create(); + + schema.vertexLabel("person") + .properties("name") + .useCustomizeStringId() + .ifNotExist() + .create(); + + schema.vertexLabel("movie") + .properties("name") + .useCustomizeStringId() + .ifNotExist() + .create(); + + schema.edgeLabel("follow") + .sourceLabel("person") + .targetLabel("person") + .ifNotExist() + .create(); + + schema.edgeLabel("like") + .sourceLabel("person") + .targetLabel("movie") + .ifNotExist() + .create(); + + schema.edgeLabel("directedBy") + .sourceLabel("movie") + .targetLabel("person") + .ifNotExist() + .create(); + + Vertex O = graph.addVertex(T.label, "person", T.id, "O", "name", "O"); + + Vertex A = graph.addVertex(T.label, "person", T.id, "A", "name", "A"); + Vertex B = graph.addVertex(T.label, "person", T.id, "B", "name", "B"); + Vertex C = graph.addVertex(T.label, "person", T.id, "C", "name", "C"); + Vertex D = graph.addVertex(T.label, "person", T.id, "D", "name", "D"); + + Vertex E = graph.addVertex(T.label, "movie", T.id, "E", "name", "E"); + Vertex F = graph.addVertex(T.label, "movie", T.id, "F", "name", "F"); + Vertex G = graph.addVertex(T.label, "movie", T.id, "G", "name", "G"); + Vertex H = graph.addVertex(T.label, "movie", T.id, "H", "name", "H"); + Vertex I = graph.addVertex(T.label, "movie", T.id, "I", "name", "I"); + Vertex J = graph.addVertex(T.label, "movie", T.id, "J", "name", "J"); + + Vertex K = graph.addVertex(T.label, "person", T.id, "K", "name", "K"); + Vertex L = graph.addVertex(T.label, "person", T.id, "L", "name", "L"); + Vertex M = graph.addVertex(T.label, "person", T.id, "M", "name", "M"); + + O.addEdge("follow", A); + O.addEdge("follow", B); + O.addEdge("follow", C); + D.addEdge("follow", O); + + A.addEdge("follow", B); + A.addEdge("like", E); + A.addEdge("like", F); + + B.addEdge("like", G); + B.addEdge("like", H); + + C.addEdge("like", I); + C.addEdge("like", J); + + E.addEdge("directedBy", K); + F.addEdge("directedBy", B); + F.addEdge("directedBy", L); + + G.addEdge("directedBy", M); + } + + @AfterClass + public static void clearNeighborRankGraph() { + List taskIds = new ArrayList<>(); + taskIds.add(edgeLabelAPI.delete("directedBy")); + taskIds.add(edgeLabelAPI.delete("like")); + taskIds.add(edgeLabelAPI.delete("follow")); + taskIds.forEach(BaseApiTest::waitUntilTaskCompleted); + taskIds.clear(); + taskIds.add(vertexLabelAPI.delete("movie")); + taskIds.add(vertexLabelAPI.delete("person")); + taskIds.forEach(BaseApiTest::waitUntilTaskCompleted); + } + + @Test + public void testNeighborRank() { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source("O"); + builder.steps().direction(Direction.OUT).degree(-1).top(10); + builder.steps().direction(Direction.OUT).degree(-1).top(10); + builder.steps().direction(Direction.OUT).degree(-1).top(10); + builder.alpha(0.9).capacity(-1); + NeighborRankAPI.Request request = builder.build(); + + List ranks = neighborRankAPI.post(request); + Assert.assertEquals(4, ranks.size()); + Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0)); + Assert.assertEquals(ImmutableMap.of("B", 0.4305D, "A", 0.3D, "C", 0.3D), + ranks.get(1)); + Assert.assertEquals(ImmutableMap.builder() + .put("G", 0.17550000000000002D) + .put("H", 0.17550000000000002D) + .put("I", 0.135D) + .put("J", 0.135D) + .put("E", 0.09000000000000001D) + .put("F", 0.09000000000000001D) + .build(), + ranks.get(2)); + Assert.assertEquals(ImmutableMap.of("M", 0.15795D, + "K", 0.08100000000000002D, + "L", 0.04050000000000001D), + ranks.get(3)); + } + + @Test + public void testNeighborRankWithOtherAlpha() { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source("O"); + builder.steps().direction(Direction.OUT).degree(-1).top(10); + builder.steps().direction(Direction.OUT).degree(-1).top(10); + builder.steps().direction(Direction.OUT).degree(-1).top(10); + builder.alpha(1.0).capacity(-1); + NeighborRankAPI.Request request = builder.build(); + + List ranks = neighborRankAPI.post(request); + Assert.assertEquals(4, ranks.size()); + Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0)); + Assert.assertEquals(ImmutableMap.of("B", 0.5D, + "A", 0.3333333333333333D, + "C", 0.3333333333333333D), + ranks.get(1)); + Assert.assertEquals(ImmutableMap.builder() + .put("G", 0.2222222222222222D) + .put("H", 0.2222222222222222D) + .put("I", 0.16666666666666666D) + .put("J", 0.16666666666666666D) + .put("E", 0.1111111111111111D) + .put("F", 0.1111111111111111D) + .build(), + ranks.get(2)); + Assert.assertEquals(ImmutableMap.of("M", 0.2222222222222222D, + "K", 0.1111111111111111D, + "L", 0.05555555555555555D), + ranks.get(3)); + } + + @Test + public void testNeighborRankWithDirection() { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source("O"); + builder.steps().direction(Direction.BOTH); + builder.steps().direction(Direction.IN); + builder.steps().direction(Direction.OUT); + builder.alpha(0.9).capacity(-1); + NeighborRankAPI.Request request = builder.build(); + + List ranks = neighborRankAPI.post(request); + Assert.assertEquals(4, ranks.size()); + Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0)); + Assert.assertEquals(ImmutableMap.of("A", 0.32625000000000004D, + "B", 0.27056250000000004D, + "C", 0.225D, + "D", 0.225D), + ranks.get(1)); + Assert.assertEquals(ImmutableMap.of("F", 0.10125D), + ranks.get(2)); + Assert.assertEquals(ImmutableMap.of("L", 0.045562500000000006D), + ranks.get(3)); + } + + @Test + public void testNeighborRankWithLabels() { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source("O"); + builder.steps().labels("follow").direction(Direction.OUT); + builder.steps().labels("like").direction(Direction.OUT); + builder.steps().labels("directedBy").direction(Direction.OUT); + builder.alpha(0.9).capacity(-1); + NeighborRankAPI.Request request = builder.build(); + + List ranks = neighborRankAPI.post(request); + Assert.assertEquals(4, ranks.size()); + Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0)); + Assert.assertEquals(ImmutableMap.of("B", 0.36075D, + "A", 0.3D, + "C", 0.3D), + ranks.get(1)); + Assert.assertEquals(ImmutableMap.builder() + .put("E", 0.135) + .put("F", 0.135) + .put("G", 0.135) + .put("H", 0.135) + .put("I", 0.135) + .put("J", 0.135) + .build(), + ranks.get(2)); + Assert.assertEquals(ImmutableMap.of("K", 0.12150000000000001D, + "M", 0.12150000000000001D, + "L", 0.060750000000000005D), + ranks.get(3)); + } + + @Test + public void testNeighborRankWithTop() { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source("O"); + builder.steps().direction(Direction.OUT).degree(-1).top(2); + builder.steps().direction(Direction.OUT).degree(-1).top(3); + builder.steps().direction(Direction.OUT).degree(-1).top(2); + builder.alpha(0.9).capacity(-1); + NeighborRankAPI.Request request = builder.build(); + + List ranks = neighborRankAPI.post(request); + Assert.assertEquals(4, ranks.size()); + Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0)); + Assert.assertEquals(ImmutableMap.of("B", 0.4305D, "A", 0.3D), + ranks.get(1)); + Assert.assertEquals(ImmutableMap.of("G", 0.17550000000000002D, + "H", 0.17550000000000002D, + "I", 0.135D), + ranks.get(2)); + Assert.assertEquals(ImmutableMap.of("M", 0.15795D, + "K", 0.08100000000000002D), + ranks.get(3)); + } + + @Test + public void testNeighborRankWithDegree() { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source("O"); + builder.steps().direction(Direction.OUT).degree(2); + builder.steps().direction(Direction.OUT).degree(1); + builder.steps().direction(Direction.OUT).degree(1); + builder.alpha(0.9).capacity(-1); + NeighborRankAPI.Request request = builder.build(); + + List ranks = neighborRankAPI.post(request); + Assert.assertEquals(4, ranks.size()); + Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0)); + Assert.assertEquals(ImmutableMap.of("B", 0.855D, "A", 0.45D), + ranks.get(1)); + Assert.assertEquals(ImmutableMap.of("G", 0.7695D), ranks.get(2)); + Assert.assertEquals(ImmutableMap.of("M", 0.69255D), ranks.get(3)); + + builder = NeighborRankAPI.Request.builder(); + builder.source("O"); + builder.steps().direction(Direction.OUT).degree(2); + builder.steps().direction(Direction.OUT).degree(2); + builder.steps().direction(Direction.OUT).degree(1); + builder.alpha(0.9).capacity(-1); + request = builder.build(); + + ranks = neighborRankAPI.post(request); + Assert.assertEquals(4, ranks.size()); + Assert.assertEquals(ImmutableMap.of("O", 1.0D), ranks.get(0)); + Assert.assertEquals(ImmutableMap.of("B", 0.6525000000000001D, + "A", 0.45D), + ranks.get(1)); + Assert.assertEquals(ImmutableMap.of("G", 0.293625D, + "H", 0.293625D, + "E", 0.2025D), + ranks.get(2)); + Assert.assertEquals(ImmutableMap.of("M", 0.2642625D, + "K", 0.18225000000000002D), + ranks.get(3)); + } + + @Test + public void testNeighborRankWithCapacity() { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source("O"); + builder.steps().direction(Direction.OUT); + builder.steps().direction(Direction.OUT); + builder.steps().direction(Direction.OUT); + builder.alpha(0.9).capacity(1); + NeighborRankAPI.Request request = builder.build(); + + Assert.assertThrows(ServerException.class, () -> { + neighborRankAPI.post(request); + }); + } + + @Test + public void testNeighborRankWithIsolatedVertex() { + Vertex isolate = graph().addVertex(T.label, "person", T.id, "isolate", + "name", "isolate-vertex"); + + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source("isolate").alpha(0.9); + builder.steps().direction(Direction.BOTH); + NeighborRankAPI.Request request = builder.build(); + + List ranks = neighborRankAPI.post(request); + Assert.assertEquals(2, ranks.size()); + Assert.assertEquals(ImmutableMap.of("isolate", 1.0D), ranks.get(0)); + Assert.assertEquals(ImmutableMap.of(), ranks.get(1)); + + graph().removeVertex(isolate.id()); + } + + @Test + public void testNeighborRankWithInvalidParams() { + // Invalid source + Assert.assertThrows(IllegalArgumentException.class, () -> { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source(null); + }); + + // Invalid degree + Assert.assertThrows(IllegalArgumentException.class, () -> { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.steps().degree(-2); + }); + + // Invalid top + Assert.assertThrows(IllegalArgumentException.class, () -> { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.steps().top(0); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.steps().top(1001); + }); + + // Invalid alpha + Assert.assertThrows(IllegalArgumentException.class, () -> { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.alpha(0.0); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.alpha(1.1); + }); + + // Invalid capacity + Assert.assertThrows(IllegalArgumentException.class, () -> { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.capacity(-2); + }); + + // Without steps + Assert.assertThrows(IllegalArgumentException.class, () -> { + NeighborRankAPI.Request.Builder builder; + builder = NeighborRankAPI.Request.builder(); + builder.source("A"); + builder.build(); + }); + } +} diff --git a/src/test/java/com/baidu/hugegraph/api/PersonalRankApiTest.java b/src/test/java/com/baidu/hugegraph/api/PersonalRankApiTest.java new file mode 100644 index 000000000..ad297fe07 --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/api/PersonalRankApiTest.java @@ -0,0 +1,310 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.api; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.baidu.hugegraph.api.traverser.PersonalRankAPI; +import com.baidu.hugegraph.driver.GraphManager; +import com.baidu.hugegraph.driver.SchemaManager; +import com.baidu.hugegraph.structure.constant.T; +import com.baidu.hugegraph.structure.graph.Vertex; +import com.baidu.hugegraph.testutil.Assert; +import com.google.common.collect.ImmutableMap; + +public class PersonalRankApiTest extends BaseApiTest { + + @BeforeClass + public static void initPersonalRankGraph() { + GraphManager graph = graph(); + SchemaManager schema = schema(); + + schema.propertyKey("name").asText().ifNotExist().create(); + + schema.vertexLabel("person") + .properties("name") + .useCustomizeStringId() + .ifNotExist() + .create(); + + schema.vertexLabel("movie") + .properties("name") + .useCustomizeStringId() + .ifNotExist() + .create(); + + schema.edgeLabel("like") + .sourceLabel("person") + .targetLabel("movie") + .ifNotExist() + .create(); + + Vertex A = graph.addVertex(T.label, "person", T.id, "A", "name", "A"); + Vertex B = graph.addVertex(T.label, "person", T.id, "B", "name", "B"); + Vertex C = graph.addVertex(T.label, "person", T.id, "C", "name", "C"); + + Vertex a = graph.addVertex(T.label, "movie", T.id, "a", "name", "a"); + Vertex b = graph.addVertex(T.label, "movie", T.id, "b", "name", "b"); + Vertex c = graph.addVertex(T.label, "movie", T.id, "c", "name", "c"); + Vertex d = graph.addVertex(T.label, "movie", T.id, "d", "name", "d"); + + A.addEdge("like", a); + A.addEdge("like", c); + + B.addEdge("like", a); + B.addEdge("like", b); + B.addEdge("like", c); + B.addEdge("like", d); + + C.addEdge("like", c); + C.addEdge("like", d); + } + + @AfterClass + public static void clearPersonalRankGraph() { + List taskIds = new ArrayList<>(); + taskIds.add(edgeLabelAPI.delete("like")); + taskIds.forEach(BaseApiTest::waitUntilTaskCompleted); + taskIds.clear(); + taskIds.add(vertexLabelAPI.delete("movie")); + taskIds.add(vertexLabelAPI.delete("person")); + taskIds.forEach(BaseApiTest::waitUntilTaskCompleted); + } + + @Test + public void testPersonalRank() { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.source("A").label("like").alpha(0.9).maxDepth(50); + PersonalRankAPI.Request request = builder.build(); + + Map ranks = personalRankAPI.post(request); + Map expectedRanks = ImmutableMap.of( + "B", 0.2065750574989044D, + "C", 0.09839507219265439D, + "d", 0.08959757100230095D, + "b", 0.04589958822642998D + ); + Assert.assertEquals(expectedRanks, ranks); + } + + @Test + public void testPersonalRankWithWithLabel() { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.source("A").label("like").alpha(0.9).maxDepth(50) + .withLabel(PersonalRankAPI.Request.WithLabel.SAME_LABEL); + PersonalRankAPI.Request request = builder.build(); + + Map ranks = personalRankAPI.post(request); + Map expectedRanks = ImmutableMap.of( + "B", 0.2065750574989044D, + "C", 0.09839507219265439D + ); + Assert.assertEquals(expectedRanks, ranks); + + builder = PersonalRankAPI.Request.builder(); + builder.source("A").label("like").alpha(0.9).maxDepth(50) + .withLabel(PersonalRankAPI.Request.WithLabel.OTHER_LABEL); + request = builder.build(); + + ranks = personalRankAPI.post(request); + expectedRanks = ImmutableMap.of( + "d", 0.08959757100230095D, + "b", 0.04589958822642998D + ); + Assert.assertEquals(expectedRanks, ranks); + } + + @Test + public void testPersonalRankWithOtherAlpha() { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.source("A").label("like").alpha(1).maxDepth(50); + PersonalRankAPI.Request request = builder.build(); + + Map ranks = personalRankAPI.post(request); + Map expectedRanks = ImmutableMap.of( + "B", 0.5D, + "C", 0.24999999999999956D, + "b", 0.0D, + "d", 0.0D + ); + Assert.assertEquals(expectedRanks, ranks); + } + + @Test + public void testPersonalRankWithDegree() { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + + builder.source("A").label("like").alpha(0.9).degree(1).maxDepth(1); + PersonalRankAPI.Request request = builder.build(); + + // Removed root and direct neighbors of root + Map ranks = personalRankAPI.post(request); + Assert.assertEquals(ImmutableMap.of(), ranks); + + builder.source("A").label("like").alpha(0.9).degree(1).maxDepth(2); + request = builder.build(); + + ranks = personalRankAPI.post(request); + Assert.assertEquals(ImmutableMap.of(), ranks); + + builder.source("A").label("like").alpha(0.9).degree(2).maxDepth(1); + request = builder.build(); + + ranks = personalRankAPI.post(request); + Assert.assertEquals(ImmutableMap.of(), ranks); + + builder.source("A").label("like").alpha(0.9).degree(2).maxDepth(2); + request = builder.build(); + + ranks = personalRankAPI.post(request); + Assert.assertEquals(ImmutableMap.of("B", 0.405D), ranks); + } + + @Test + public void testPersonalRankWithLimit() { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.source("A").label("like").alpha(0.9).limit(3).maxDepth(50); + PersonalRankAPI.Request request = builder.build(); + + Map ranks = personalRankAPI.post(request); + Map expectedRanks = ImmutableMap.of( + "B", 0.2065750574989044D, + "C", 0.09839507219265439D, + "d", 0.08959757100230095D + ); + Assert.assertEquals(expectedRanks, ranks); + } + + @Test + public void testPersonalRankWithMaxDepth() { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.source("A").label("like").alpha(0.9).maxDepth(20); + PersonalRankAPI.Request request = builder.build(); + + Map ranks = personalRankAPI.post(request); + Map expectedRanks = ImmutableMap.of( + "B", 0.23414889646372697D, + "C", 0.11218194186115384D, + "d", 0.07581065434649958D, + "b", 0.03900612828909826D + ); + Assert.assertEquals(expectedRanks, ranks); + } + + @Test + public void testPersonalRankWithUnsorted() { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.source("A").label("like").alpha(0.9).maxDepth(50).sorted(false); + PersonalRankAPI.Request request = builder.build(); + + Map ranks = personalRankAPI.post(request); + Map expectedRanks = ImmutableMap.of( + "b", 0.04589958822642998D, + "B", 0.2065750574989044D, + "C", 0.09839507219265439D, + "d", 0.08959757100230095D + ); + Assert.assertEquals(expectedRanks, ranks); + } + + @Test + public void testPersonalRankWithIsolatedVertex() { + Vertex isolate = graph().addVertex(T.label, "person", T.id, "isolate", + "name", "isolate-vertex"); + + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.source("isolate").label("like").alpha(0.9).maxDepth(50); + PersonalRankAPI.Request request = builder.build(); + + Map ranks = personalRankAPI.post(request); + Assert.assertEquals(ImmutableMap.of(), ranks); + + graph().removeVertex(isolate.id()); + } + + @Test + public void testPersonalRankWithInvalidParams() { + // Invalid source + Assert.assertThrows(IllegalArgumentException.class, () -> { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.source(null); + }); + + // Invalid label + Assert.assertThrows(IllegalArgumentException.class, () -> { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.label(null); + }); + + // Invalid alpha + Assert.assertThrows(IllegalArgumentException.class, () -> { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.alpha(0.0); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.alpha(1.1); + }); + + // Invalid degree + Assert.assertThrows(IllegalArgumentException.class, () -> { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.degree(-2); + }); + + // Invalid limit + Assert.assertThrows(IllegalArgumentException.class, () -> { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.limit(-2); + }); + + // Invalid maxDepth + Assert.assertThrows(IllegalArgumentException.class, () -> { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.maxDepth(0); + }); + Assert.assertThrows(IllegalArgumentException.class, () -> { + PersonalRankAPI.Request.Builder builder; + builder = PersonalRankAPI.Request.builder(); + builder.maxDepth(51); + }); + } +} diff --git a/src/test/java/com/baidu/hugegraph/api/ShortestPathApiTest.java b/src/test/java/com/baidu/hugegraph/api/ShortestPathApiTest.java new file mode 100644 index 000000000..618d9265c --- /dev/null +++ b/src/test/java/com/baidu/hugegraph/api/ShortestPathApiTest.java @@ -0,0 +1,255 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.api; + +import java.util.List; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.baidu.hugegraph.exception.ServerException; +import com.baidu.hugegraph.structure.constant.Direction; +import com.baidu.hugegraph.structure.constant.T; +import com.baidu.hugegraph.structure.graph.Path; +import com.baidu.hugegraph.structure.graph.Vertex; +import com.baidu.hugegraph.testutil.Assert; +import com.google.common.collect.ImmutableList; + +public class ShortestPathApiTest extends BaseApiTest { + + @BeforeClass + public static void initShortestPathGraph() { + schema().vertexLabel("node") + .useCustomizeNumberId() + .ifNotExist() + .create(); + + schema().edgeLabel("link") + .sourceLabel("node").targetLabel("node") + .ifNotExist() + .create(); + + Vertex v1 = graph().addVertex(T.label, "node", T.id, 1); + Vertex v2 = graph().addVertex(T.label, "node", T.id, 2); + Vertex v3 = graph().addVertex(T.label, "node", T.id, 3); + Vertex v4 = graph().addVertex(T.label, "node", T.id, 4); + Vertex v5 = graph().addVertex(T.label, "node", T.id, 5); + Vertex v6 = graph().addVertex(T.label, "node", T.id, 6); + Vertex v7 = graph().addVertex(T.label, "node", T.id, 7); + Vertex v8 = graph().addVertex(T.label, "node", T.id, 8); + Vertex v9 = graph().addVertex(T.label, "node", T.id, 9); + Vertex v10 = graph().addVertex(T.label, "node", T.id, 10); + Vertex v11 = graph().addVertex(T.label, "node", T.id, 11); + Vertex v12 = graph().addVertex(T.label, "node", T.id, 12); + Vertex v13 = graph().addVertex(T.label, "node", T.id, 13); + Vertex v14 = graph().addVertex(T.label, "node", T.id, 14); + Vertex v15 = graph().addVertex(T.label, "node", T.id, 15); + Vertex v16 = graph().addVertex(T.label, "node", T.id, 16); + Vertex v17 = graph().addVertex(T.label, "node", T.id, 17); + Vertex v18 = graph().addVertex(T.label, "node", T.id, 18); + + // Path length 5 + v1.addEdge("link", v2); + v2.addEdge("link", v3); + v3.addEdge("link", v4); + v4.addEdge("link", v5); + v5.addEdge("link", v6); + + // Path length 4 + v1.addEdge("link", v7); + v7.addEdge("link", v8); + v8.addEdge("link", v9); + v9.addEdge("link", v6); + + // Path length 3 + v1.addEdge("link", v10); + v10.addEdge("link", v11); + v11.addEdge("link", v6); + + // Add other 3 neighbor for v7 + v7.addEdge("link", v12); + v7.addEdge("link", v13); + v7.addEdge("link", v14); + + // Add other 4 neighbor for v10 + v10.addEdge("link", v15); + v10.addEdge("link", v16); + v10.addEdge("link", v17); + v10.addEdge("link", v18); + } + + @AfterClass + public static void clearShortestPathGraph() { + waitUntilTaskCompleted(edgeLabelAPI.delete("link")); + waitUntilTaskCompleted(vertexLabelAPI.delete("node")); + } + + @Test + public void testShortestPath() { + Path path = shortestPathAPI.get(1, 6, Direction.BOTH, + null, 6, -1L, 0L, -1L); + Assert.assertEquals(4, path.size()); + Assert.assertEquals(ImmutableList.of(1, 10, 11, 6), path.objects()); + } + + @Test + public void testShortestPathWithLabel() { + Path path = shortestPathAPI.get(1, 6, Direction.BOTH, + "link", 6, -1L, 0L, -1L); + Assert.assertEquals(4, path.size()); + Assert.assertEquals(ImmutableList.of(1, 10, 11, 6), path.objects()); + } + + @Test + public void testShortestPathWithDegree() { + Path path = shortestPathAPI.get(1, 6, Direction.BOTH, + null, 6, 1L, 0L, -1L); + Assert.assertEquals(6, path.size()); + Assert.assertEquals(ImmutableList.of(1, 2, 3, 4, 5, 6), path.objects()); + } + + @Test + public void testShortestPathWithCapacity() { + Path path = shortestPathAPI.get(14, 6, Direction.BOTH, + null, 6, 5L, 0L, 19L); + Assert.assertEquals(5, path.size()); + Assert.assertEquals(ImmutableList.of(14, 7, 8, 9, 6), path.objects()); + + Assert.assertThrows(ServerException.class, () -> { + shortestPathAPI.get(14, 6, Direction.BOTH, null, 6, 1L, 0L, 2L); + }); + } + + @Test + public void testShortestPathWithMaxDepth() { + Path path = shortestPathAPI.get(14, 6, Direction.BOTH, + null, 4, 5L, 0L, 19L); + Assert.assertEquals(5, path.size()); + Assert.assertEquals(ImmutableList.of(14, 7, 8, 9, 6), path.objects()); + + path = shortestPathAPI.get(14, 6, Direction.BOTH, + null, 3, 5L, 0L, 19L); + Assert.assertEquals(0, path.size()); + } + + @Test + public void testShortestPathWithSkipDegree() { + // Path length 5 with min degree 3(v1 degree is 3) + List path1 = ImmutableList.of(1, 2, 3, 4, 5, 6); + // Path length 4 with middle degree 4(v7 degree is 4) + List path2 = ImmutableList.of(1, 7, 8, 9, 6); + // Path length 3 with max degree 5(v10 degree is 5) + List path3 = ImmutableList.of(1, 10, 11, 6); + + // (skipped degree == degree) > max degree + Path path = shortestPathAPI.get(1, 6, Direction.OUT, + null, 5, 6L, 6L, -1L); + Assert.assertEquals(4, path.size()); + Assert.assertEquals(path3, path.objects()); + + // (skipped degree == degree) == max degree + path = shortestPathAPI.get(1, 6, Direction.OUT, + null, 5, 5L, 5L, -1L); + Assert.assertEquals(5, path.size()); + Assert.assertEquals(path2, path.objects()); + + // min degree < (skipped degree == degree) == middle degree < max degree + path = shortestPathAPI.get(1, 6, Direction.OUT, + null, 5, 4L, 4L, -1L); + Assert.assertEquals(6, path.size()); + Assert.assertEquals(path1, path.objects()); + + // (skipped degree == degree) <= min degree + path = shortestPathAPI.get(1, 6, Direction.OUT, + null, 5, 3L, 3L, -1L); + Assert.assertEquals(0, path.size()); + + // Skipped degree > max degree, degree <= min degree + path = shortestPathAPI.get(1, 6, Direction.OUT, + null, 5, 3L, 6L, -1L); + Assert.assertTrue(path.size() == 4 || + path.size() == 5 || + path.size() == 6); + List> paths = ImmutableList.of(path1, path2, path3); + Assert.assertTrue(paths.contains(path.objects())); + + // Skipped degree > max degree, min degree < degree < max degree + path = shortestPathAPI.get(1, 6, Direction.OUT, + null, 5, 4L, 6L, -1L); + Assert.assertTrue(path.size() == 4 || path.size() == 5); + Assert.assertTrue(path2.equals(path.objects()) || + path3.equals(path.objects())); + + // Skipped degree > max degree, degree >= max degree + path = shortestPathAPI.get(1, 6, Direction.OUT, + null, 5, 5L, 6L, -1L); + Assert.assertEquals(4, path.size()); + Assert.assertEquals(path3, path.objects()); + } + + @Test + public void testShortestPathWithIllegalArgs() { + // The max depth shouldn't be 0 or negative + Assert.assertThrows(IllegalArgumentException.class, () -> { + shortestPathAPI.get("a", "b", Direction.BOTH, + null, -1, 1L, 0L, 2L); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + shortestPathAPI.get("a", "b", Direction.BOTH, + null, 0, 1L, 0L, 2L); + }); + + // The degree shouldn't be 0 or negative but NO_LIMIT(-1) + Assert.assertThrows(IllegalArgumentException.class, () -> { + shortestPathAPI.get("a", "b", Direction.BOTH, + null, 5, 0L, 0L, 2L); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + shortestPathAPI.get("a", "b", Direction.BOTH, + null, 5, -3L, 0L, 2L); + }); + + // The skipped degree shouldn't be negative + Assert.assertThrows(IllegalArgumentException.class, () -> { + shortestPathAPI.get("a", "b", Direction.BOTH, + null, 5, 1L, -1L, 2L); + }); + + // The skipped degree shouldn't be >= capacity + Assert.assertThrows(IllegalArgumentException.class, () -> { + shortestPathAPI.get("a", "b", Direction.BOTH, + null, 5, 1L, 2L, 2L); + }); + + // The skipped degree shouldn't be < degree + Assert.assertThrows(IllegalArgumentException.class, () -> { + shortestPathAPI.get("a", "b", Direction.BOTH, + null, 5, 3L, 2L, 10L); + }); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + shortestPathAPI.get("a", "b", Direction.BOTH, + null, 5, -1L, 2L, 10L); + }); + } +} diff --git a/src/test/java/com/baidu/hugegraph/api/TraverserApiTest.java b/src/test/java/com/baidu/hugegraph/api/TraverserApiTest.java index d1a9a06e0..f1b3df317 100644 --- a/src/test/java/com/baidu/hugegraph/api/TraverserApiTest.java +++ b/src/test/java/com/baidu/hugegraph/api/TraverserApiTest.java @@ -19,7 +19,8 @@ package com.baidu.hugegraph.api; -import java.util.ArrayList; +import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_PAGE_LIMIT; + import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -31,25 +32,17 @@ import com.baidu.hugegraph.api.traverser.structure.CrosspointsRequest; import com.baidu.hugegraph.api.traverser.structure.CustomizedCrosspoints; -import com.baidu.hugegraph.api.traverser.structure.CustomizedPaths; -import com.baidu.hugegraph.api.traverser.structure.PathsRequest; -import com.baidu.hugegraph.driver.SchemaManager; import com.baidu.hugegraph.exception.ServerException; import com.baidu.hugegraph.structure.constant.Direction; -import com.baidu.hugegraph.structure.constant.T; import com.baidu.hugegraph.structure.graph.Edge; import com.baidu.hugegraph.structure.graph.Edges; import com.baidu.hugegraph.structure.graph.Path; import com.baidu.hugegraph.structure.graph.Shard; import com.baidu.hugegraph.structure.graph.Vertex; import com.baidu.hugegraph.structure.graph.Vertices; -import com.baidu.hugegraph.structure.schema.EdgeLabel; import com.baidu.hugegraph.testutil.Assert; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -import static com.baidu.hugegraph.structure.constant.Traverser.DEFAULT_PAGE_LIMIT; public class TraverserApiTest extends BaseApiTest { @@ -63,198 +56,6 @@ public static void prepareSchemaAndGraph() { BaseApiTest.initEdge(); } - @Test - public void testShortestPath() { - Object markoId = getVertexId("person", "name", "marko"); - Object joshId = getVertexId("person", "name", "josh"); - Object rippleId = getVertexId("software", "name", "ripple"); - - Path path = shortestPathAPI.get(markoId, rippleId, Direction.BOTH, - null, 3, -1L, 0L, -1L); - Assert.assertEquals(3, path.size()); - Assert.assertEquals(markoId, path.objects().get(0)); - Assert.assertEquals(joshId, path.objects().get(1)); - Assert.assertEquals(rippleId, path.objects().get(2)); - } - - @Test - public void testShortestPathWithCapacity() { - Object markoId = getVertexId("person", "name", "marko"); - Object rippleId = getVertexId("software", "name", "ripple"); - - Assert.assertThrows(ServerException.class, () -> { - shortestPathAPI.get(markoId, rippleId, Direction.BOTH, - null, 3, 1L, 0L, 2L); - }); - } - - @Test - public void testShortestPathWithSkipDegree() { - schema().vertexLabel("node") - .useCustomizeNumberId() - .ifNotExist() - .create(); - - schema().edgeLabel("link") - .sourceLabel("node").targetLabel("node") - .ifNotExist() - .create(); - - Vertex v1 = graph().addVertex(T.label, "node", T.id, 1); - Vertex v2 = graph().addVertex(T.label, "node", T.id, 2); - Vertex v3 = graph().addVertex(T.label, "node", T.id, 3); - Vertex v4 = graph().addVertex(T.label, "node", T.id, 4); - Vertex v5 = graph().addVertex(T.label, "node", T.id, 5); - Vertex v6 = graph().addVertex(T.label, "node", T.id, 6); - Vertex v7 = graph().addVertex(T.label, "node", T.id, 7); - Vertex v8 = graph().addVertex(T.label, "node", T.id, 8); - Vertex v9 = graph().addVertex(T.label, "node", T.id, 9); - Vertex v10 = graph().addVertex(T.label, "node", T.id, 10); - Vertex v11 = graph().addVertex(T.label, "node", T.id, 11); - Vertex v12 = graph().addVertex(T.label, "node", T.id, 12); - Vertex v13 = graph().addVertex(T.label, "node", T.id, 13); - Vertex v14 = graph().addVertex(T.label, "node", T.id, 14); - Vertex v15 = graph().addVertex(T.label, "node", T.id, 15); - Vertex v16 = graph().addVertex(T.label, "node", T.id, 16); - Vertex v17 = graph().addVertex(T.label, "node", T.id, 17); - Vertex v18 = graph().addVertex(T.label, "node", T.id, 18); - - // Path length 5 - v1.addEdge("link", v2); - v2.addEdge("link", v3); - v3.addEdge("link", v4); - v4.addEdge("link", v5); - v5.addEdge("link", v6); - - // Path length 4 - v1.addEdge("link", v7); - v7.addEdge("link", v8); - v8.addEdge("link", v9); - v9.addEdge("link", v6); - - // Path length 3 - v1.addEdge("link", v10); - v10.addEdge("link", v11); - v11.addEdge("link", v6); - - // Add other 3 neighbor for v7 - v7.addEdge("link", v12); - v7.addEdge("link", v13); - v7.addEdge("link", v14); - - // Add other 4 neighbor for v10 - v10.addEdge("link", v15); - v10.addEdge("link", v16); - v10.addEdge("link", v17); - v10.addEdge("link", v18); - - // Path length 5 with min degree 3(v1 degree is 3) - List path1 = ImmutableList.of(v1.id(), v2.id(), v3.id(), - v4.id(), v5.id(), v6.id()); - // Path length 4 with middle degree 4(v7 degree is 4) - List path2 = ImmutableList.of(v1.id(), v7.id(), v8.id(), - v9.id(), v6.id()); - // Path length 3 with max degree 5(v10 degree is 5) - List path3 = ImmutableList.of(v1.id(), v10.id(), - v11.id(), v6.id()); - - // (skipped degree == degree) > max degree - Path path = shortestPathAPI.get(v1.id(), v6.id(), Direction.OUT, - null, 5, 6L, 6L, -1L); - Assert.assertEquals(4, path.size()); - Assert.assertEquals(path3, path.objects()); - - // (skipped degree == degree) == max degree - path = shortestPathAPI.get(v1.id(), v6.id(), Direction.OUT, - null, 5, 5L, 5L, -1L); - Assert.assertEquals(5, path.size()); - Assert.assertEquals(path2, path.objects()); - - // min degree < (skipped degree == degree) == middle degree < max degree - path = shortestPathAPI.get(v1.id(), v6.id(), Direction.OUT, - null, 5, 4L, 4L, -1L); - Assert.assertEquals(6, path.size()); - Assert.assertEquals(path1, path.objects()); - - // (skipped degree == degree) <= min degree - path = shortestPathAPI.get(v1.id(), v6.id(), Direction.OUT, - null, 5, 3L, 3L, -1L); - Assert.assertEquals(0, path.size()); - - // Skipped degree > max degree, degree <= min degree - path = shortestPathAPI.get(v1.id(), v6.id(), Direction.OUT, - null, 5, 3L, 6L, -1L); - Assert.assertTrue(path.size() == 4 || - path.size() == 5 || - path.size() == 6); - List> paths = ImmutableList.of(path1, path2, path3); - Assert.assertTrue(paths.contains(path.objects())); - - // Skipped degree > max degree, min degree < degree < max degree - path = shortestPathAPI.get(v1.id(), v6.id(), Direction.OUT, - null, 5, 4L, 6L, -1L); - Assert.assertTrue(path.size() == 4 || path.size() == 5); - Assert.assertTrue(path2.equals(path.objects()) || - path3.equals(path.objects())); - - // Skipped degree > max degree, degree >= max degree - path = shortestPathAPI.get(v1.id(), v6.id(), Direction.OUT, - null, 5, 5L, 6L, -1L); - Assert.assertEquals(4, path.size()); - Assert.assertEquals(path3, path.objects()); - - waitUntilTaskCompleted(edgeLabelAPI.delete("link")); - waitUntilTaskCompleted(vertexLabelAPI.delete("node")); - } - - @Test - public void testShortestPathWithIllegalArgs() { - // The max depth shouldn't be 0 or negative - Assert.assertThrows(IllegalArgumentException.class, () -> { - shortestPathAPI.get("a", "b", Direction.BOTH, - null, -1, 1L, 0L, 2L); - }); - - Assert.assertThrows(IllegalArgumentException.class, () -> { - shortestPathAPI.get("a", "b", Direction.BOTH, - null, 0, 1L, 0L, 2L); - }); - - // The degree shouldn't be 0 or negative but NO_LIMIT(-1) - Assert.assertThrows(IllegalArgumentException.class, () -> { - shortestPathAPI.get("a", "b", Direction.BOTH, - null, 5, 0L, 0L, 2L); - }); - - Assert.assertThrows(IllegalArgumentException.class, () -> { - shortestPathAPI.get("a", "b", Direction.BOTH, - null, 5, -3L, 0L, 2L); - }); - - // The skipped degree shouldn't be negative - Assert.assertThrows(IllegalArgumentException.class, () -> { - shortestPathAPI.get("a", "b", Direction.BOTH, - null, 5, 1L, -1L, 2L); - }); - - // The skipped degree shouldn't be >= capacity - Assert.assertThrows(IllegalArgumentException.class, () -> { - shortestPathAPI.get("a", "b", Direction.BOTH, - null, 5, 1L, 2L, 2L); - }); - - // The skipped degree shouldn't be < degree - Assert.assertThrows(IllegalArgumentException.class, () -> { - shortestPathAPI.get("a", "b", Direction.BOTH, - null, 5, 3L, 2L, 10L); - }); - - Assert.assertThrows(IllegalArgumentException.class, () -> { - shortestPathAPI.get("a", "b", Direction.BOTH, - null, 5, -1L, 2L, 10L); - }); - } - @Test public void testPaths() { Object markoId = getVertexId("person", "name", "marko"); @@ -594,291 +395,6 @@ public void testRaysWithCapacity() { }); } - @Test - public void testCustomizedPathsSourceLabelProperty() { - initEdgesWithWeights(); - - Object markoId = getVertexId("person", "name", "marko"); - Object joshId = getVertexId("person", "name", "josh"); - Object rippleId = getVertexId("software", "name", "ripple"); - Object lopId = getVertexId("software", "name", "lop"); - - PathsRequest.Builder builder = new PathsRequest.Builder(); - builder.sources().label("person").property("name", "marko"); - builder.steps().direction(Direction.OUT).labels("knows1") - .weightBy("weight").degree(-1); - builder.steps().direction(Direction.OUT).labels("created1") - .weightBy("weight").degree(-1); - builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) - .capacity(-1).limit(-1); - PathsRequest request = builder.build(); - - CustomizedPaths customizedPaths = customizedPathsAPI.post(request); - List paths = customizedPaths.paths(); - - Assert.assertEquals(2, paths.size()); - - List path1 = ImmutableList.of(markoId, joshId, lopId); - List path2 = ImmutableList.of(markoId, joshId, rippleId); - Assert.assertEquals(path1, paths.get(0).objects()); - Assert.assertEquals(path2, paths.get(1).objects()); - - List weights1 = ImmutableList.of(1.0D, 0.4D); - List weights2 = ImmutableList.of(1.0D, 1.0D); - Assert.assertEquals(weights1, paths.get(0).weights()); - Assert.assertEquals(weights2, paths.get(1).weights()); - - Set vertices = customizedPaths.vertices().stream() - .map(Vertex::id) - .collect(Collectors.toSet()); - Assert.assertEquals(4, vertices.size()); - Set expectedVertices = ImmutableSet.of(markoId, lopId, - rippleId, joshId); - Assert.assertEquals(expectedVertices, vertices); - removeEdgesWithWeights(); - } - - @Test - public void testCustomizedPathsSourceIds() { - initEdgesWithWeights(); - - Object markoId = getVertexId("person", "name", "marko"); - Object lopId = getVertexId("software", "name", "lop"); - Object peterId = getVertexId("person", "name", "peter"); - - PathsRequest.Builder builder = new PathsRequest.Builder(); - builder.sources().ids(markoId, peterId); - builder.steps().direction(Direction.OUT).labels("created1") - .weightBy("weight").degree(-1); - builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) - .capacity(-1).limit(-1); - PathsRequest request = builder.build(); - - CustomizedPaths customizedPaths = customizedPathsAPI.post(request); - List paths = customizedPaths.paths(); - - Assert.assertEquals(2, paths.size()); - - List path1 = ImmutableList.of(markoId, lopId); - List path2 = ImmutableList.of(peterId, lopId); - List> expectedPaths = ImmutableList.of(path1, path2); - Assert.assertTrue(expectedPaths.contains(paths.get(0).objects())); - Assert.assertTrue(expectedPaths.contains(paths.get(1).objects())); - - List weights1 = ImmutableList.of(0.2D); - List weights2 = ImmutableList.of(0.4D); - List> expectedWeights = ImmutableList.of(weights1, - weights2); - Assert.assertTrue(expectedWeights.contains(paths.get(0).weights())); - Assert.assertTrue(expectedWeights.contains(paths.get(1).weights())); - - Set vertices = customizedPaths.vertices().stream() - .map(Vertex::id) - .collect(Collectors.toSet()); - Assert.assertEquals(3, vertices.size()); - Set expectedVertices = ImmutableSet.of(markoId, lopId, peterId); - Assert.assertEquals(expectedVertices, vertices); - removeEdgesWithWeights(); - } - - @Test - public void testCustomizedPathsSourceLabelPropertyMultiValue() { - initEdgesWithWeights(); - - Object markoId = getVertexId("person", "name", "marko"); - Object lopId = getVertexId("software", "name", "lop"); - Object peterId = getVertexId("person", "name", "peter"); - - PathsRequest.Builder builder = new PathsRequest.Builder(); - List names = ImmutableList.of("marko", "peter"); - builder.sources().label("person").property("name", names); - builder.steps().direction(Direction.OUT).labels("created1") - .weightBy("weight").degree(-1); - builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) - .capacity(-1).limit(-1); - PathsRequest request = builder.build(); - - CustomizedPaths customizedPaths = customizedPathsAPI.post(request); - List paths = customizedPaths.paths(); - - Assert.assertEquals(2, paths.size()); - - List path1 = ImmutableList.of(markoId, lopId); - List path2 = ImmutableList.of(peterId, lopId); - List> expectedPaths = ImmutableList.of(path1, path2); - Assert.assertTrue(expectedPaths.contains(paths.get(0).objects())); - Assert.assertTrue(expectedPaths.contains(paths.get(1).objects())); - - List weights1 = ImmutableList.of(0.2D); - List weights2 = ImmutableList.of(0.4D); - List> expectedWeights = ImmutableList.of(weights1, - weights2); - Assert.assertTrue(expectedWeights.contains(paths.get(0).weights())); - Assert.assertTrue(expectedWeights.contains(paths.get(1).weights())); - - Set vertices = customizedPaths.vertices().stream() - .map(Vertex::id) - .collect(Collectors.toSet()); - Assert.assertEquals(3, vertices.size()); - Set expectedVertices = ImmutableSet.of(markoId, lopId, peterId); - Assert.assertEquals(expectedVertices, vertices); - removeEdgesWithWeights(); - } - - @Test - public void testCustomizedPathsWithSample() { - initEdgesWithWeights(); - - Object markoId = getVertexId("person", "name", "marko"); - Object joshId = getVertexId("person", "name", "josh"); - Object rippleId = getVertexId("software", "name", "ripple"); - Object lopId = getVertexId("software", "name", "lop"); - - PathsRequest.Builder builder = new PathsRequest.Builder(); - builder.sources().label("person").property("name", "marko"); - builder.steps().direction(Direction.OUT).labels("knows1") - .weightBy("weight").degree(-1); - builder.steps().direction(Direction.OUT).labels("created1") - .weightBy("weight").degree(-1).sample(1); - builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) - .capacity(-1).limit(-1); - PathsRequest request = builder.build(); - - CustomizedPaths customizedPaths = customizedPathsAPI.post(request); - List paths = customizedPaths.paths(); - - Assert.assertEquals(1, paths.size()); - - List path1 = ImmutableList.of(markoId, joshId, rippleId); - List path2 = ImmutableList.of(markoId, joshId, lopId); - List> expectedPaths = ImmutableList.of(path1, path2); - Assert.assertTrue(expectedPaths.contains(paths.get(0).objects())); - - List weights1 = ImmutableList.of(1D, 0.4D); - List weights2 = ImmutableList.of(1D, 1D); - - Assert.assertTrue(weights1.equals(paths.get(0).weights()) || - weights2.equals(paths.get(0).weights())); - - Set vertices = customizedPaths.vertices().stream() - .map(Vertex::id) - .collect(Collectors.toSet()); - Assert.assertEquals(3, vertices.size()); - Assert.assertTrue(path1.containsAll(vertices) || - path2.containsAll(vertices)); - removeEdgesWithWeights(); - } - - @Test - public void testCustomizedPathsWithDecr() { - initEdgesWithWeights(); - - Object markoId = getVertexId("person", "name", "marko"); - Object joshId = getVertexId("person", "name", "josh"); - Object rippleId = getVertexId("software", "name", "ripple"); - Object lopId = getVertexId("software", "name", "lop"); - - PathsRequest.Builder builder = new PathsRequest.Builder(); - builder.sources().label("person").property("name", "marko"); - builder.steps().direction(Direction.OUT).labels("knows1") - .weightBy("weight").degree(-1); - builder.steps().direction(Direction.OUT).labels("created1") - .weightBy("weight").degree(-1); - builder.sortBy(PathsRequest.SortBy.DECR).withVertex(true) - .capacity(-1).limit(-1); - PathsRequest request = builder.build(); - - CustomizedPaths customizedPaths = customizedPathsAPI.post(request); - List paths = customizedPaths.paths(); - - Assert.assertEquals(2, paths.size()); - - List path1 = ImmutableList.of(markoId, joshId, rippleId); - List path2 = ImmutableList.of(markoId, joshId, lopId); - Assert.assertEquals(path1, paths.get(0).objects()); - Assert.assertEquals(path2, paths.get(1).objects()); - - List weights1 = ImmutableList.of(1.0D, 1.0D); - List weights2 = ImmutableList.of(1.0D, 0.4D); - Assert.assertEquals(weights1, paths.get(0).weights()); - Assert.assertEquals(weights2, paths.get(1).weights()); - - Set vertices = customizedPaths.vertices().stream() - .map(Vertex::id) - .collect(Collectors.toSet()); - Assert.assertEquals(4, vertices.size()); - Set expectedVertices = ImmutableSet.of(markoId, lopId, - rippleId, joshId); - Assert.assertEquals(expectedVertices, vertices); - removeEdgesWithWeights(); - } - - @Test - public void testCustomizedPathsWithLimit() { - initEdgesWithWeights(); - - Object markoId = getVertexId("person", "name", "marko"); - Object joshId = getVertexId("person", "name", "josh"); - Object rippleId = getVertexId("software", "name", "ripple"); - Object lopId = getVertexId("software", "name", "lop"); - - PathsRequest.Builder builder = new PathsRequest.Builder(); - builder.sources().label("person").property("name", "marko"); - builder.steps().direction(Direction.OUT).labels("knows1") - .weightBy("weight").degree(-1); - builder.steps().direction(Direction.OUT).labels("created1") - .weightBy("weight").degree(-1); - builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) - .capacity(-1).limit(1); - PathsRequest request = builder.build(); - - CustomizedPaths customizedPaths = customizedPathsAPI.post(request); - List paths = customizedPaths.paths(); - - Assert.assertEquals(1, paths.size()); - - List path1 = ImmutableList.of(markoId, joshId, lopId); - List path2 = ImmutableList.of(markoId, joshId, rippleId); - List> expectedPaths = ImmutableList.of(path1, path2); - Assert.assertTrue(expectedPaths.contains(paths.get(0).objects())); - - List weights1 = ImmutableList.of(1.0D, 0.4D); - List weights2 = ImmutableList.of(1.0D, 1.0D); - List> expectedWeights = ImmutableList.of(weights1, - weights2); - Assert.assertTrue(expectedWeights.contains(paths.get(0).weights())); - - Set vertices = customizedPaths.vertices().stream() - .map(Vertex::id) - .collect(Collectors.toSet()); - Assert.assertEquals(3, vertices.size()); - Set vertices1 = ImmutableSet.of(markoId, lopId, joshId); - Set vertices2 = ImmutableSet.of(markoId, lopId, rippleId); - Set> expectedVertices = ImmutableSet.of(vertices1, vertices2); - Assert.assertTrue(expectedVertices.contains(vertices)); - removeEdgesWithWeights(); - } - - @Test - public void testCustomizedPathsWithCapacity() { - initEdgesWithWeights(); - - PathsRequest.Builder builder = new PathsRequest.Builder(); - builder.sources().label("person").property("name", "marko"); - builder.steps().direction(Direction.OUT).labels("knows1") - .weightBy("weight").degree(-1); - builder.steps().direction(Direction.OUT).labels("created1") - .weightBy("weight").degree(-1); - builder.sortBy(PathsRequest.SortBy.INCR).withVertex(true) - .capacity(1).limit(-1); - PathsRequest request = builder.build(); - - Assert.assertThrows(ServerException.class, () -> { - customizedPathsAPI.post(request); - }); - removeEdgesWithWeights(); - } - @Test public void testCustomizedCrosspoints() { Object lopId = getVertexId("software", "name", "lop"); @@ -1058,48 +574,4 @@ public void testScanEdgeWithSplitSizeLt1MB() { edgesAPI.shards(1 * 1024 * 1024 - 1); }); } - - - private static void initEdgesWithWeights() { - SchemaManager schema = schema(); - schema.edgeLabel("knows1") - .sourceLabel("person") - .targetLabel("person") - .properties("date", "weight") - .nullableKeys("weight") - .ifNotExist() - .create(); - - schema.edgeLabel("created1") - .sourceLabel("person") - .targetLabel("software") - .properties("date", "weight") - .nullableKeys("weight") - .ifNotExist() - .create(); - - Vertex marko = getVertex("person", "name", "marko"); - Vertex vadas = getVertex("person", "name", "vadas"); - Vertex lop = getVertex("software", "name", "lop"); - Vertex josh = getVertex("person", "name", "josh"); - Vertex ripple = getVertex("software", "name", "ripple"); - Vertex peter = getVertex("person", "name", "peter"); - - marko.addEdge("knows1", vadas, "date", "20160110", "weight", 0.5); - marko.addEdge("knows1", josh, "date", "20130220", "weight", 1.0); - marko.addEdge("created1", lop, "date", "20171210", "weight", 0.4); - josh.addEdge("created1", lop, "date", "20091111", "weight", 0.4); - josh.addEdge("created1", ripple, "date", "20171210", "weight", 1.0); - peter.addEdge("created1", lop, "date", "20170324", "weight", 0.2); - } - - private static void removeEdgesWithWeights() { - List elTaskIds = new ArrayList<>(); - EdgeLabel knows1 = schema().getEdgeLabel("knows1"); - EdgeLabel created1 = schema().getEdgeLabel("created1"); - ImmutableList.of(knows1, created1).forEach(edgeLabel -> { - elTaskIds.add(edgeLabelAPI.delete(edgeLabel.name())); - }); - elTaskIds.forEach(BaseApiTest::waitUntilTaskCompleted); - } }