You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hugegraph.apache.org by "msgui (via GitHub)" <gi...@apache.org> on 2023/07/11 16:57:58 UTC

[GitHub] [incubator-hugegraph] msgui opened a new pull request, #2242: feat: optimising adjacency edge queries

msgui opened a new pull request, #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242

   <!-- 
     Thank you very much for contributing to Apache HugeGraph, we are happy that you want to help us improve it!
   
     Here are some tips for you:
       1. If this is your first time, please read the [contributing guidelines](https://github.com/apache/hugegraph/blob/master/CONTRIBUTING.md)
   
       2. If a PR fix/close an issue, type the message "close xxx" (xxx is the link of related 
   issue) in the content, GitHub will auto link it (Required)
   
       3. Name the PR title in "Google Commit Format", start with "feat | fix | perf | refactor | doc | chore", 
         such like: "feat(core): support the PageRank algorithm" or "fix: wrong break in the compute loop" (module is optional)
         skip it if you are unsure about which is the best component.
   
       4. One PR address one issue, better not to mix up multiple issues.
   
       5. Put an `x` in the `[ ]` to mark the item as CHECKED. `[x]` (or click it directly after 
   published)
   -->
   
   ## Purpose of the PR
   
   - I have completed Task 13-6.
   <img width="439" alt="Task13-6" src="https://github.com/apache/incubator-hugegraph/assets/87920097/c8cc0b32-ebed-4464-ad3f-931ef2525881">
   
   <!--
   Please explain more context in this section, clarify why the changes are needed. 
   e.g:
   - If you propose a new API, clarify the use case for a new API.
   - If you fix a bug, you can clarify why it is a bug, and should be associated with an issue.
   -->
   
   ## Main Changes
   
   I have added the EdgeExistenceAPI and EdgeExistenceTraverser, which provide enhanced queries for checking the existence of adjacency edges.
   <!-- Please clarify what changes you are proposing. The purpose of this section is to outline the changes and how this PR fixes the issue. These change logs are helpful for better ant faster reviews.)
   
   For example:
   
   - If you introduce a new feature, please show detailed design here or add the link of design documentation.
   - If you refactor some codes with changing classes, showing the class hierarchy will help reviewers.
   - If there is a discussion in the mailing list, please add the link. -->
   
   ## Verifying these changes
   
   <!-- Please pick the proper options below -->
   
   - [ ] Trivial rework / code cleanup without any test coverage. (No Need)
   - [ ] Already covered by existing tests, such as *(please modify tests here)*.
   - [x] Need tests and can be verified as follows:
       - graph: ![graph](https://github.com/apache/incubator-hugegraph/assets/87920097/a808a065-7426-403c-96db-424104ebad4a)
   
   	-  **GET** http://**{ip:port}**/graphs/**{graph}**/traversers/edgeexistence?source=2:lop&target=1:vadas&edgelabel=knows
   	![query1](https://github.com/apache/incubator-hugegraph/assets/87920097/a00263e5-31cf-4ba5-83c8-a75459fc00e2)
   
   	- **GET** http://**{ip:port}**/graphs/**{graph}**/traversers/edgeexistence?source=1:marko&target=1:vadas
   	![query2](https://github.com/apache/incubator-hugegraph/assets/87920097/25e8f66c-0f62-4f08-86bd-b3ab2c5d01af)
   
   	- **GET** http://**{ip:port}**/graphs/**{graph}**/traversers/edgeexistence?source=1:marko
   	 ![query3](https://github.com/apache/incubator-hugegraph/assets/87920097/2e7bd4a9-8351-4a6c-9dbd-bde05e25d5d2)
   	- **GET** http://**{ip:port}**/graphs/**{graph}**/traversers/edgeexistence?source=2:lop&target=1:vadas&edgelabel=knows 
   	<img alt="query4" src="https://github.com/apache/incubator-hugegraph/assets/87920097/d409c374-ffc7-48f8-af31-2fc14b8674d9">
   
   ## Does this PR potentially affect the following parts?
   
   <!-- DO NOT REMOVE THIS SECTION. CHECK THE PROPER BOX ONLY. -->
   
   - [x]  Nope
   - [ ]  Dependencies (add/update license info) <!-- Don't forget to add/update the info in "LICENSE" & "NOTICE" files (both in root & dist module) -->
   - [ ]  Modify configurations
   - [ ]  The public API
   - [ ]  Other affects (typed here)
   
   ## Documentation Status
   
   <!-- DO NOT REMOVE THIS SECTION. CHECK THE PROPER BOX ONLY. -->
   
   - [ ]  `Doc - TODO` <!-- Your PR changes impact docs and you will update later -->
   - [ ]  `Doc - Done` <!-- Related docs have been already added or updated -->
   - [x]  `Doc - No Need` <!-- Your PR changes don't impact/need docs -->
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1398121015


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,64 @@
+/*
+ * 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 org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.iterator.FilterIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {

Review Comment:
   can we add a comment here
    `"If no label provided, fallback to slow query by filtering"`



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -52,12 +52,12 @@ public String get(@Context GraphManager manager,
                       @QueryParam("source") String source,
                       @QueryParam("target") String target,
                       @QueryParam("label") String edgeLabel,
-                      @QueryParam("sortValues")
+                      @QueryParam("sort_values")
                       @DefaultValue(DEFAULT_EMPTY) String sortValues,
                       @QueryParam("limit")
                       @DefaultValue(DEFAULT_LIMIT) long limit) {
         LOG.debug("Graph [{}] get edgeexistence with " +
-                "source '{}', target '{}', edgeLabel '{}', sortValue '{}'and limit '{}'",
+                "source '{}'and target '{}'and edgeLabel '{}'and sortValue '{}'and limit '{}'",

Review Comment:
   `and` => `,`?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme merged PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1324613092


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbors(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.limit(limit);
+        if (edgeLabel.existSortKeys()) {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        } else {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, "");
+        }
+        return graph().edges(conditionQuery);
+    }
+
+    private Iterator<Edge> queryByNeighbors(Id sourceId, Id targetId, long limit) {
+        ListIterator<Edge> edges = QueryResults.toList(this.edgesOfVertex(sourceId, Directions.OUT, (Id) null, limit));

Review Comment:
   don't need to cast to ListIterator here, just keep Iterator type



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbors(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.limit(limit);
+        if (edgeLabel.existSortKeys()) {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        } else {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, "");
+        }
+        return graph().edges(conditionQuery);
+    }
+
+    private Iterator<Edge> queryByNeighbors(Id sourceId, Id targetId, long limit) {
+        ListIterator<Edge> edges = QueryResults.toList(this.edgesOfVertex(sourceId, Directions.OUT, (Id) null, limit));
+        List<Edge> results = newList();

Review Comment:
   prefer to use ListIterator instead to avoid oom



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1278307839


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   > expect sortValues here?
   
   Hi @javeme  ,so, is this pic what you mean?
   
    ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/f17a3e96-b277-4108-a0e7-788b5c09aeab)
   
    I'm a bit confused about how to handle the 'sortKeys' and 'sortValues' thing. Should I use 'eq', 'key', or something else? Can you help me out and make it clearer?



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   > expect sortValues here?
   
   Hi @javeme  ,so, is this pic what you mean?
   
    ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/f17a3e96-b277-4108-a0e7-788b5c09aeab)
   
    I'm a bit confused about how to handle the 'sortKeys' and 'sortValues' thing. Should I use 'eq', 'key', or something else? Can you help me out and make it clearer?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1407796933


##########
hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+
+@Path("graphs/{graph}/traversers/edgeexist")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")

Review Comment:
   > seems better to add swagger annotation for users to visit? (enable it & basic desc if we need)
   > 
   > could refer [#2337 (files)](https://github.com/apache/incubator-hugegraph/pull/2337/files)
   
    I ve added the summary using the 'operation' annotation



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1261969141


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,48 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(
+        Id sourceId, Id targetId,
+        String label, long limit) {
+        if ("BOTH".equals(label)) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, getEdgeLabelId(label));
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, "");

Review Comment:
   > please check if exists sortkey in the edge label, fallback if yes
   
   Hi @javeme , how exactly is the fallback implemented? I'm not quite sure which aspects of ConditionQuery can utilize EdgeLabel.sortkeys.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "imbajin (via GitHub)" <gi...@apache.org>.
imbajin commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1407639100


##########
hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+
+@Path("graphs/{graph}/traversers/edgeexist")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")

Review Comment:
   seems better to add swagger annotation for users to visit?
   
   could refer https://github.com/apache/incubator-hugegraph/pull/2337/files



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1275968202


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   expect sortValues here?



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,61 @@
+package org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import com.google.common.collect.Lists;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+import java.util.List;
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    private static final Logger LOG = Log.logger(EdgeExistenceAPI.class);
+    private static final String DEFAULT_EMPTY = "";
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(@Context GraphManager manager,
+                      @PathParam("graph") String graph,
+                      @QueryParam("source") String source,
+                      @QueryParam("target") String target,
+                      @QueryParam("edgelabel") String edgeLabel,
+                      @QueryParam("sortValues")
+                      @DefaultValue(DEFAULT_EMPTY) String sortValues,
+                      @QueryParam("limit")
+                      @DefaultValue(DEFAULT_LIMIT) long limit) {
+        LOG.debug("Graph [{}] get edgeexistence with " +
+                "source '{}', target '{}', edgeLabel '{}', sortValue '{}'and limit '{}'",
+            graph, source, target, edgeLabel, sortValues, limit);
+
+        E.checkArgumentNotNull(source, "The source can't be null");
+        E.checkArgumentNotNull(target, "The target can't be null");
+
+        Id sourceId = HugeVertex.getIdValue(source);
+        Id targetId = HugeVertex.getIdValue(target);
+        HugeGraph hugeGraph = graph(manager, graph);

Review Comment:
   hugeGraph => hugegraph



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,61 @@
+package org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import com.google.common.collect.Lists;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+import java.util.List;
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    private static final Logger LOG = Log.logger(EdgeExistenceAPI.class);
+    private static final String DEFAULT_EMPTY = "";
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(@Context GraphManager manager,
+                      @PathParam("graph") String graph,
+                      @QueryParam("source") String source,
+                      @QueryParam("target") String target,
+                      @QueryParam("edgelabel") String edgeLabel,
+                      @QueryParam("sortValues")
+                      @DefaultValue(DEFAULT_EMPTY) String sortValues,
+                      @QueryParam("limit")
+                      @DefaultValue(DEFAULT_LIMIT) long limit) {
+        LOG.debug("Graph [{}] get edgeexistence with " +
+                "source '{}', target '{}', edgeLabel '{}', sortValue '{}'and limit '{}'",
+            graph, source, target, edgeLabel, sortValues, limit);
+
+        E.checkArgumentNotNull(source, "The source can't be null");
+        E.checkArgumentNotNull(target, "The target can't be null");
+
+        Id sourceId = HugeVertex.getIdValue(source);
+        Id targetId = HugeVertex.getIdValue(target);
+        HugeGraph hugeGraph = graph(manager, graph);
+        EdgeExistenceTraverser traverser = new EdgeExistenceTraverser(hugeGraph);
+
+        Iterator<Edge> edges = traverser.queryEdgeExistence(sourceId, targetId, edgeLabel, sortValues, limit);
+
+        List<Edge> all = Lists.newArrayList(edges);
+        return manager.serializer(hugeGraph).writeList("edges", all);

Review Comment:
   can we just serialize the iterator instead of a list



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);
+        }
+        return graph().edges(conditionQuery);
+    }
+
+    private Iterator<Edge> queryByNeighbor(Id sourceId, Id targetId, long limit) {
+        Iterator<Edge> edges = this.edgesOfVertex(sourceId, Directions.OUT, (Id) null, limit);
+        List<Edge> res = new ArrayList<>();

Review Comment:
   use QueryResult.ListIterator?



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);
+        }
+        return graph().edges(conditionQuery);
+    }
+
+    private Iterator<Edge> queryByNeighbor(Id sourceId, Id targetId, long limit) {
+        Iterator<Edge> edges = this.edgesOfVertex(sourceId, Directions.OUT, (Id) null, limit);
+        List<Edge> res = new ArrayList<>();
+        String target = targetId.toString();
+        while (edges.hasNext()) {
+            Edge edge = edges.next();
+            String outVertexId = edge.inVertex().id().toString();
+            if (!target.equals(outVertexId)) continue;

Review Comment:
   adjust the code style



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1278307811


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   Hi @imbajin ,so, is this pic what you mean?
   
    ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/f17a3e96-b277-4108-a0e7-788b5c09aeab)
   
    I'm a bit confused about how to handle the 'sortKeys' and 'sortValues' thing. Should I use 'eq', 'key', or something else? Can you help me out and make it clearer?



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   Hi @imbajin ,so, is this pic what you mean?
   
    ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/f17a3e96-b277-4108-a0e7-788b5c09aeab)
   
    I'm a bit confused about how to handle the 'sortKeys' and 'sortValues' thing. Should I use 'eq', 'key', or something else? Can you help me out and make it clearer?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1278307839


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   > expect sortValues here?
   
   Hi @javeme  ,so, is this pic what you mean?
    ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/f17a3e96-b277-4108-a0e7-788b5c09aeab)
   
    😥I'm a bit confused about how to handle the 'sortKeys' and 'sortValues' thing. Should I use 'eq', 'key', or something else? Could you help me out and make it clearer?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] imbajin commented on pull request #2242: feat: optimising adjacency edge queries

Posted by "imbajin (via GitHub)" <gi...@apache.org>.
imbajin commented on PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#issuecomment-1631844567

   Thanks, could also open a summary issue for it (let other people know the progress of it & comment to assign)
   
   BTW, before submit PR we could open a single issue for it first (and discuss the main context then finish it) 🔢 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1278308287


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,61 @@
+package org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import com.google.common.collect.Lists;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+import java.util.List;
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    private static final Logger LOG = Log.logger(EdgeExistenceAPI.class);
+    private static final String DEFAULT_EMPTY = "";
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(@Context GraphManager manager,
+                      @PathParam("graph") String graph,
+                      @QueryParam("source") String source,
+                      @QueryParam("target") String target,
+                      @QueryParam("edgelabel") String edgeLabel,
+                      @QueryParam("sortValues")
+                      @DefaultValue(DEFAULT_EMPTY) String sortValues,
+                      @QueryParam("limit")
+                      @DefaultValue(DEFAULT_LIMIT) long limit) {
+        LOG.debug("Graph [{}] get edgeexistence with " +
+                "source '{}', target '{}', edgeLabel '{}', sortValue '{}'and limit '{}'",
+            graph, source, target, edgeLabel, sortValues, limit);
+
+        E.checkArgumentNotNull(source, "The source can't be null");
+        E.checkArgumentNotNull(target, "The target can't be null");
+
+        Id sourceId = HugeVertex.getIdValue(source);
+        Id targetId = HugeVertex.getIdValue(target);
+        HugeGraph hugeGraph = graph(manager, graph);
+        EdgeExistenceTraverser traverser = new EdgeExistenceTraverser(hugeGraph);
+
+        Iterator<Edge> edges = traverser.queryEdgeExistence(sourceId, targetId, edgeLabel, sortValues, limit);
+
+        List<Edge> all = Lists.newArrayList(edges);
+        return manager.serializer(hugeGraph).writeList("edges", all);

Review Comment:
   > can we just serialize the iterator instead of a list
   
   Hi @javeme,are you referring to this pic?
   
   ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/34fad57c-a0b7-44d5-80b5-6a9ed69d6696)
    



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,61 @@
+package org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import com.google.common.collect.Lists;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+import java.util.List;
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    private static final Logger LOG = Log.logger(EdgeExistenceAPI.class);
+    private static final String DEFAULT_EMPTY = "";
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(@Context GraphManager manager,
+                      @PathParam("graph") String graph,
+                      @QueryParam("source") String source,
+                      @QueryParam("target") String target,
+                      @QueryParam("edgelabel") String edgeLabel,
+                      @QueryParam("sortValues")
+                      @DefaultValue(DEFAULT_EMPTY) String sortValues,
+                      @QueryParam("limit")
+                      @DefaultValue(DEFAULT_LIMIT) long limit) {
+        LOG.debug("Graph [{}] get edgeexistence with " +
+                "source '{}', target '{}', edgeLabel '{}', sortValue '{}'and limit '{}'",
+            graph, source, target, edgeLabel, sortValues, limit);
+
+        E.checkArgumentNotNull(source, "The source can't be null");
+        E.checkArgumentNotNull(target, "The target can't be null");
+
+        Id sourceId = HugeVertex.getIdValue(source);
+        Id targetId = HugeVertex.getIdValue(target);
+        HugeGraph hugeGraph = graph(manager, graph);
+        EdgeExistenceTraverser traverser = new EdgeExistenceTraverser(hugeGraph);
+
+        Iterator<Edge> edges = traverser.queryEdgeExistence(sourceId, targetId, edgeLabel, sortValues, limit);
+
+        List<Edge> all = Lists.newArrayList(edges);
+        return manager.serializer(hugeGraph).writeList("edges", all);

Review Comment:
   > can we just serialize the iterator instead of a list
   
   Hi @javeme,are you referring to this pic?
   
   ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/34fad57c-a0b7-44d5-80b5-6a9ed69d6696)
    



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#issuecomment-1821190022

   > It seems fine now, Thanks. Next step let’s adapt the client and add some test cases. how-to: [hugegraph/hugegraph-client#84](https://github.com/hugegraph/hugegraph-client/pull/84)
   Ok, it's done. Currently, the client CI tests are showing a 404 error. It seems like we'll need this PR merged first before we can test it properly.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1278575349


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   please node the sortKeys is shared by all edges with a specified label.
   we can simply fallback if exist sortKeys



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1390426185


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+
+@Path("graphs/{graph}/traversers/edgeexist")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    private static final Logger LOG = Log.logger(EdgeExistenceAPI.class);
+    private static final String DEFAULT_EMPTY = "";
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(@Context GraphManager manager,
+                      @PathParam("graph") String graph,
+                      @QueryParam("source") String source,
+                      @QueryParam("target") String target,
+                      @QueryParam("edgeLabel") String edgeLabel,
+                      @QueryParam("sortValues")

Review Comment:
   expect the style `label`/`sort_values` like this: 
   https://github.com/apache/incubator-hugegraph/blob/bce6d058f5d1f108b4c19e18eb7a65ab0604a526/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/SingleSourceShortestPathAPI.java#L66



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+
+@Path("graphs/{graph}/traversers/edgeexist")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    private static final Logger LOG = Log.logger(EdgeExistenceAPI.class);
+    private static final String DEFAULT_EMPTY = "";
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(@Context GraphManager manager,
+                      @PathParam("graph") String graph,
+                      @QueryParam("source") String source,
+                      @QueryParam("target") String target,
+                      @QueryParam("edgeLabel") String edgeLabel,
+                      @QueryParam("sortValues")
+                      @DefaultValue(DEFAULT_EMPTY) String sortValues,
+                      @QueryParam("limit")
+                      @DefaultValue(DEFAULT_LIMIT) long limit) {
+        LOG.debug("Graph [{}] get edgeexistence with " +
+                "source '{}', target '{}', edgeLabel '{}', sortValue '{}'and limit '{}'",
+            graph, source, target, edgeLabel, sortValues, limit);

Review Comment:
   align with `"` :
   ```java
           LOG.debug("Graph [{}] get edgeexistence with " +
                     "source '{}', target '{}', edgeLabel '{}', sortValue '{}'and limit '{}'",
                     graph, source, target, edgeLabel, sortValues, limit);
   ```



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbors(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.limit(limit);
+        if (edgeLabel.existSortKeys()) {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        } else {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, "");
+        }
+        return graph().edges(conditionQuery);
+    }
+
+    private Iterator<Edge> queryByNeighbors(Id sourceId, Id targetId, long limit) {
+        Iterator<Edge> edges = this.edgesOfVertex(sourceId, Directions.OUT, (Id) null, limit);
+        List<Edge> results = newList();
+        while (edges.hasNext()){

Review Comment:
   we can use FilterIterator instead: https://github.com/apache/incubator-hugegraph/blob/bce6d058f5d1f108b4c19e18eb7a65ab0604a526/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/OltpTraverser.java#L239



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbors(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);

Review Comment:
   unused var?



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbors(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.limit(limit);
+        if (edgeLabel.existSortKeys()) {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        } else {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, "");
+        }
+        return graph().edges(conditionQuery);
+    }
+
+    private Iterator<Edge> queryByNeighbors(Id sourceId, Id targetId, long limit) {
+        Iterator<Edge> edges = this.edgesOfVertex(sourceId, Directions.OUT, (Id) null, limit);
+        List<Edge> results = newList();
+        while (edges.hasNext()){
+            Edge edge = edges.next();
+            if (targetId.compareTo((Id) edge.inVertex().id()) == 0) {

Review Comment:
   we can call `targetId.equals(edge.otherVertexId())`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1390436936


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbors(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);

Review Comment:
   > unused var?
   
   line 53



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#issuecomment-1802670536

   Due to the lack of activity, the current pr is marked as stale and will be closed after 180 days, any update will remove the stale label


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#issuecomment-1827415968

   please pull the latest master code and do `git rebase -i master` on this commit


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1407796933


##########
hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+
+@Path("graphs/{graph}/traversers/edgeexist")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")

Review Comment:
   > seems better to add swagger annotation for users to visit? (enable it & basic desc if we need)
   > 
   > could refer [#2337 (files)](https://github.com/apache/incubator-hugegraph/pull/2337/files)
   
    thx,I ve added the summary using the 'operation' annotation



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1278307811


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   Hi @imbajin ,so, is this pic what you mean?
   
    ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/f17a3e96-b277-4108-a0e7-788b5c09aeab)
   
    I'm a bit confused about how to handle the 'sortKeys' and 'sortValues' thing. Should I use 'eq', 'key', or something else? Can you help me out and make it clearer?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1279165187


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   > please node the sortKeys is shared by all edges with a specified label.
   > we can simply fallback if exist sortKeys
   
   @javeme  Is this the pic you were expecting?
   ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/45d4aa10-8650-41b6-9a83-d27aeef96919)
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1278575040


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,61 @@
+package org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import com.google.common.collect.Lists;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+import java.util.List;
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    private static final Logger LOG = Log.logger(EdgeExistenceAPI.class);
+    private static final String DEFAULT_EMPTY = "";
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(@Context GraphManager manager,
+                      @PathParam("graph") String graph,
+                      @QueryParam("source") String source,
+                      @QueryParam("target") String target,
+                      @QueryParam("edgelabel") String edgeLabel,
+                      @QueryParam("sortValues")
+                      @DefaultValue(DEFAULT_EMPTY) String sortValues,
+                      @QueryParam("limit")
+                      @DefaultValue(DEFAULT_LIMIT) long limit) {
+        LOG.debug("Graph [{}] get edgeexistence with " +
+                "source '{}', target '{}', edgeLabel '{}', sortValue '{}'and limit '{}'",
+            graph, source, target, edgeLabel, sortValues, limit);
+
+        E.checkArgumentNotNull(source, "The source can't be null");
+        E.checkArgumentNotNull(target, "The target can't be null");
+
+        Id sourceId = HugeVertex.getIdValue(source);
+        Id targetId = HugeVertex.getIdValue(target);
+        HugeGraph hugeGraph = graph(manager, graph);
+        EdgeExistenceTraverser traverser = new EdgeExistenceTraverser(hugeGraph);
+
+        Iterator<Edge> edges = traverser.queryEdgeExistence(sourceId, targetId, edgeLabel, sortValues, limit);
+
+        List<Edge> all = Lists.newArrayList(edges);
+        return manager.serializer(hugeGraph).writeList("edges", all);

Review Comment:
   yes



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1261969141


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,48 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(
+        Id sourceId, Id targetId,
+        String label, long limit) {
+        if ("BOTH".equals(label)) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, getEdgeLabelId(label));
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, "");

Review Comment:
   > please check if exists sortkey in the edge label, fallback if yes
   
   How exactly is the fallback implemented? I'm not quite sure which aspects of ConditionQuery can utilize EdgeLabel.sortkeys.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1391085794


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+
+@Path("graphs/{graph}/traversers/edgeexist")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    private static final Logger LOG = Log.logger(EdgeExistenceAPI.class);
+    private static final String DEFAULT_EMPTY = "";
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(@Context GraphManager manager,
+                      @PathParam("graph") String graph,
+                      @QueryParam("source") String source,
+                      @QueryParam("target") String target,
+                      @QueryParam("label") String edgeLabel,
+                      @QueryParam("sortValues")

Review Comment:
   sortValues => sort_values



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+
+@Path("graphs/{graph}/traversers/edgeexist")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    private static final Logger LOG = Log.logger(EdgeExistenceAPI.class);
+    private static final String DEFAULT_EMPTY = "";
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(@Context GraphManager manager,
+                      @PathParam("graph") String graph,
+                      @QueryParam("source") String source,
+                      @QueryParam("target") String target,
+                      @QueryParam("label") String edgeLabel,
+                      @QueryParam("sortValues")
+                      @DefaultValue(DEFAULT_EMPTY) String sortValues,
+                      @QueryParam("limit")
+                      @DefaultValue(DEFAULT_LIMIT) long limit) {
+        LOG.debug("Graph [{}] get edgeexistence with " +
+                "source '{}', target '{}', edgeLabel '{}', sortValue '{}'and limit '{}'",

Review Comment:
   expect a space `'{}'and`



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbors(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);

Review Comment:
   ok.
   but we need to call `graph().edgeLabel(Id id)` here



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1400966836


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -57,8 +57,8 @@ public String get(@Context GraphManager manager,
                       @QueryParam("limit")
                       @DefaultValue(DEFAULT_LIMIT) long limit) {
         LOG.debug("Graph [{}] get edgeexistence with " +
-                "source '{}'and target '{}'and edgeLabel '{}'and sortValue '{}'and limit '{}'",
-                graph, source, target, edgeLabel, sortValues, limit);
+                  "source '{}', target '{}', edgeLabel '{}', sortValue '{}' and, limit '{}'",

Review Comment:
   also remove the "and"



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#issuecomment-1826215851

   TODO: update apiversion like https://github.com/apache/incubator-hugegraph/pull/2360#issuecomment-1825128789


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1261162899


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,57 @@
+package org.apache.hugegraph.api.traversers;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(
+        @Context GraphManager manager,
+        @PathParam("graph") String graph,
+        @QueryParam("source") String source,
+        @QueryParam("target") String target,
+        @QueryParam("edgelabel")
+        @DefaultValue("BOTH") String edgeLabel,
+        @QueryParam("limit")
+        @DefaultValue("1000") long limit) {
+
+        E.checkArgumentNotNull(source, "The source can't be null");
+        E.checkArgumentNotNull(target, "The target can't be null");
+
+        Id sourceId = HugeVertex.getIdValue(source);
+        Id targetId = HugeVertex.getIdValue(target);
+        HugeGraph hugeGraph = graph(manager, graph);
+        EdgeExistenceTraverser traverser = new EdgeExistenceTraverser(hugeGraph);
+
+        Iterator<Edge> edges = traverser.queryEdgeExistence(sourceId, targetId, edgeLabel, limit);
+
+        List<Id> all = new ArrayList<>();
+        while (edges.hasNext()) {
+            all.add((Id) edges.next().id());
+        }
+        return manager.serializer(hugeGraph).writeList("EdgeIds", all);
+    }
+
+

Review Comment:
   unexpected blank lines



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,57 @@
+package org.apache.hugegraph.api.traversers;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(
+        @Context GraphManager manager,
+        @PathParam("graph") String graph,
+        @QueryParam("source") String source,
+        @QueryParam("target") String target,
+        @QueryParam("edgelabel")
+        @DefaultValue("BOTH") String edgeLabel,
+        @QueryParam("limit")
+        @DefaultValue("1000") long limit) {
+
+        E.checkArgumentNotNull(source, "The source can't be null");
+        E.checkArgumentNotNull(target, "The target can't be null");
+
+        Id sourceId = HugeVertex.getIdValue(source);
+        Id targetId = HugeVertex.getIdValue(target);
+        HugeGraph hugeGraph = graph(manager, graph);
+        EdgeExistenceTraverser traverser = new EdgeExistenceTraverser(hugeGraph);
+
+        Iterator<Edge> edges = traverser.queryEdgeExistence(sourceId, targetId, edgeLabel, limit);
+
+        List<Id> all = new ArrayList<>();
+        while (edges.hasNext()) {
+            all.add((Id) edges.next().id());
+        }
+        return manager.serializer(hugeGraph).writeList("EdgeIds", all);

Review Comment:
   EdgeIds => edges
   



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,57 @@
+package org.apache.hugegraph.api.traversers;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(
+        @Context GraphManager manager,
+        @PathParam("graph") String graph,
+        @QueryParam("source") String source,
+        @QueryParam("target") String target,
+        @QueryParam("edgelabel")
+        @DefaultValue("BOTH") String edgeLabel,
+        @QueryParam("limit")
+        @DefaultValue("1000") long limit) {
+
+        E.checkArgumentNotNull(source, "The source can't be null");
+        E.checkArgumentNotNull(target, "The target can't be null");
+
+        Id sourceId = HugeVertex.getIdValue(source);
+        Id targetId = HugeVertex.getIdValue(target);
+        HugeGraph hugeGraph = graph(manager, graph);
+        EdgeExistenceTraverser traverser = new EdgeExistenceTraverser(hugeGraph);
+
+        Iterator<Edge> edges = traverser.queryEdgeExistence(sourceId, targetId, edgeLabel, limit);
+
+        List<Id> all = new ArrayList<>();

Review Comment:
   prefer to just return the edges itself?



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,48 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(
+        Id sourceId, Id targetId,
+        String label, long limit) {
+        if ("BOTH".equals(label)) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, getEdgeLabelId(label));
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, "");

Review Comment:
   please check if exists sortkey in the edge label, fallback if yes



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,57 @@
+package org.apache.hugegraph.api.traversers;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(
+        @Context GraphManager manager,
+        @PathParam("graph") String graph,
+        @QueryParam("source") String source,
+        @QueryParam("target") String target,
+        @QueryParam("edgelabel")
+        @DefaultValue("BOTH") String edgeLabel,

Review Comment:
   keep edgeLabel=null by default



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,57 @@
+package org.apache.hugegraph.api.traversers;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+@Path("graphs/{graph}/traversers/edgeexistence")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")
+public class EdgeExistenceAPI extends TraverserAPI {
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_JSON_WITH_CHARSET)
+    public String get(
+        @Context GraphManager manager,
+        @PathParam("graph") String graph,
+        @QueryParam("source") String source,
+        @QueryParam("target") String target,
+        @QueryParam("edgelabel")
+        @DefaultValue("BOTH") String edgeLabel,
+        @QueryParam("limit")
+        @DefaultValue("1000") long limit) {

Review Comment:
   use const var instead? please reference other apis



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,48 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(
+        Id sourceId, Id targetId,
+        String label, long limit) {
+        if ("BOTH".equals(label)) {

Review Comment:
   direction?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#issuecomment-1632803713

   Hi @javeme, I have addressed the reviews. Is there anything else that needs improvement? 😀


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] codecov[bot] commented on pull request #2242: feat: optimising adjacency edge queries

Posted by "codecov[bot] (via GitHub)" <gi...@apache.org>.
codecov[bot] commented on PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#issuecomment-1631197992

   ## [Codecov](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2242?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
   > Merging [#2242](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2242?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) (17790d9) into [master](https://app.codecov.io/gh/apache/incubator-hugegraph/commit/8ee3d32b4ffcb6b27d6d5762783039866c0a9147?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) (8ee3d32) will **decrease** coverage by `10.85%`.
   > The diff coverage is `0.00%`.
   
   ```diff
   @@              Coverage Diff              @@
   ##             master    #2242       +/-   ##
   =============================================
   - Coverage     65.03%   54.19%   -10.85%     
   + Complexity      979      905       -74     
   =============================================
     Files           498      500        +2     
     Lines         40682    40715       +33     
     Branches       5681     5684        +3     
   =============================================
   - Hits          26458    22065     -4393     
   - Misses        11596    16356     +4760     
   + Partials       2628     2294      -334     
   ```
   
   
   | [Impacted Files](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2242?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
   |---|---|---|
   | [...che/hugegraph/api/traversers/EdgeExistenceAPI.java](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2242?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVnZWdyYXBoLWFwaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaHVnZWdyYXBoL2FwaS90cmF2ZXJzZXJzL0VkZ2VFeGlzdGVuY2VBUEkuamF2YQ==) | `0.00% <0.00%> (ø)` | |
   | [...ph/traversal/algorithm/EdgeExistenceTraverser.java](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2242?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVnZWdyYXBoLWNvcmUvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2h1Z2VncmFwaC90cmF2ZXJzYWwvYWxnb3JpdGhtL0VkZ2VFeGlzdGVuY2VUcmF2ZXJzZXIuamF2YQ==) | `0.00% <0.00%> (ø)` | |
   
   ... and [119 files with indirect coverage changes](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2242/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   
   :mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1261969141


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,48 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(
+        Id sourceId, Id targetId,
+        String label, long limit) {
+        if ("BOTH".equals(label)) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, getEdgeLabelId(label));
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, "");

Review Comment:
   > please check if exists sortkey in the edge label, fallback if yes
   
   Hi @javeme , how exactly is the fallback implemented? I'm not quite sure which aspects of ConditionQuery can utilize EdgeLabel.sortkeys.



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,48 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(
+        Id sourceId, Id targetId,
+        String label, long limit) {
+        if ("BOTH".equals(label)) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, getEdgeLabelId(label));
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, "");

Review Comment:
   > please check if exists sortkey in the edge label, fallback if yes
   
   Hi @javeme , how exactly is the fallback implemented? I'm not quite sure which aspects of ConditionQuery can utilize EdgeLabel.sortkeys.



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,48 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(
+        Id sourceId, Id targetId,
+        String label, long limit) {
+        if ("BOTH".equals(label)) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, getEdgeLabelId(label));
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, "");

Review Comment:
   > please check if exists sortkey in the edge label, fallback if yes
   
   Hi @javeme , how exactly is the fallback implemented? I'm not quite sure which aspects of ConditionQuery can utilize EdgeLabel.sortkeys.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] msgui commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "msgui (via GitHub)" <gi...@apache.org>.
msgui commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1278307839


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,62 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.auth.HugeTarget;
+import org.apache.hugegraph.auth.HugeUser;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.IdQuery;
+import org.apache.hugegraph.backend.query.Query;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.schema.PropertyKey;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        List<Id> sortKeys = edgeLabel.sortKeys();
+
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        conditionQuery.limit(limit);
+        if (sortKeys != null) {
+            List<String> names = graph().mapPkId2Name(sortKeys);
+            conditionQuery.key(HugeKeys.SORT_KEYS, names);

Review Comment:
   > expect sortValues here?
   
   Hi @javeme  ,so, is this pic what you mean?
    ![image](https://github.com/apache/incubator-hugegraph/assets/87920097/f17a3e96-b277-4108-a0e7-788b5c09aeab)
   
    😥I'm a bit confused about how to handle the 'sortKeys' and 'sortValues' thing. Should I use 'eq', 'key', or something else? Can you help me out and make it clearer?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2242: feat: optimising adjacency edge queries

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1320681394


##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,49 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.limit(limit);
+        if (edgeLabel.existSortKeys()) {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        }else {

Review Comment:
   expect a space before "else"



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,57 @@
+package org.apache.hugegraph.api.traversers;

Review Comment:
   please add license header



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,49 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {

Review Comment:
   expect a blank line after class define



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,49 @@
+package org.apache.hugegraph.traversal.algorithm;

Review Comment:
   please add license header



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,49 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.limit(limit);
+        if (edgeLabel.existSortKeys()) {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        }else {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, "");
+        }
+        return graph().edges(conditionQuery);
+    }
+
+    private Iterator<Edge> queryByNeighbor(Id sourceId, Id targetId, long limit) {
+        ListIterator<Edge> edges = QueryResults.toList(this.edgesOfVertex(sourceId, Directions.OUT, (Id) null, limit));
+        List<Edge> res = newList();
+        edges.forEachRemaining(edge -> {if (targetId.compareTo((Id) edge.inVertex().id()) == 0)  res.add(edge);});

Review Comment:
   can we use for-loop instead? to keep a consistent style and reduce the times of callbacks



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,57 @@
+package org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+
+@Path("graphs/{graph}/traversers/edgeexistence")

Review Comment:
   `edgeexist` is ok



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,49 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.limit(limit);
+        if (edgeLabel.existSortKeys()) {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        }else {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, "");
+        }
+        return graph().edges(conditionQuery);
+    }
+
+    private Iterator<Edge> queryByNeighbor(Id sourceId, Id targetId, long limit) {
+        ListIterator<Edge> edges = QueryResults.toList(this.edgesOfVertex(sourceId, Directions.OUT, (Id) null, limit));
+        List<Edge> res = newList();

Review Comment:
   prefer results



##########
hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/EdgeExistenceTraverser.java:
##########
@@ -0,0 +1,49 @@
+package org.apache.hugegraph.traversal.algorithm;
+
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.backend.query.ConditionQuery;
+import org.apache.hugegraph.backend.query.QueryResults;
+import org.apache.hugegraph.iterator.ListIterator;
+import org.apache.hugegraph.schema.EdgeLabel;
+import org.apache.hugegraph.type.HugeType;
+import org.apache.hugegraph.type.define.Directions;
+import org.apache.hugegraph.type.define.HugeKeys;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class EdgeExistenceTraverser extends HugeTraverser {
+    public EdgeExistenceTraverser(HugeGraph graph) {
+        super(graph);
+    }
+
+    public Iterator<Edge> queryEdgeExistence(Id sourceId, Id targetId, String label,
+                                             String sortValues, long limit) {
+        if (label == null || label.isEmpty()) {
+            return queryByNeighbor(sourceId, targetId, limit);
+        }
+        Id edgeLabelId = getEdgeLabelId(label);
+        EdgeLabel edgeLabel = EdgeLabel.undefined(graph(), edgeLabelId);
+        ConditionQuery conditionQuery = new ConditionQuery(HugeType.EDGE);
+        conditionQuery.eq(HugeKeys.OWNER_VERTEX, sourceId);
+        conditionQuery.eq(HugeKeys.OTHER_VERTEX, targetId);
+        conditionQuery.eq(HugeKeys.LABEL, edgeLabelId);
+        conditionQuery.eq(HugeKeys.DIRECTION, Directions.OUT);
+        conditionQuery.limit(limit);
+        if (edgeLabel.existSortKeys()) {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, sortValues);
+        }else {
+            conditionQuery.eq(HugeKeys.SORT_VALUES, "");
+        }
+        return graph().edges(conditionQuery);
+    }
+
+    private Iterator<Edge> queryByNeighbor(Id sourceId, Id targetId, long limit) {

Review Comment:
   prefer queryByNeighbors



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat: optimising adjacency edge queries [incubator-hugegraph]

Posted by "imbajin (via GitHub)" <gi...@apache.org>.
imbajin commented on code in PR #2242:
URL: https://github.com/apache/incubator-hugegraph/pull/2242#discussion_r1407639100


##########
hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/traversers/EdgeExistenceAPI.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.hugegraph.api.traversers;
+
+import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_LIMIT;
+
+import com.codahale.metrics.annotation.Timed;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.HugeGraph;
+import org.apache.hugegraph.backend.id.Id;
+import org.apache.hugegraph.core.GraphManager;
+import org.apache.hugegraph.structure.HugeVertex;
+import org.apache.hugegraph.traversal.algorithm.EdgeExistenceTraverser;
+import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.Log;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+
+@Path("graphs/{graph}/traversers/edgeexist")
+@Singleton
+@Tag(name = "EdgeExistenceAPI")

Review Comment:
   seems better to add swagger annotation for users to visit? (enable it & basic desc if we need)
   
   could refer https://github.com/apache/incubator-hugegraph/pull/2337/files



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org