diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/ConditionQuery.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/ConditionQuery.java index b00030b76e..ac7a6124ca 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/ConditionQuery.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/ConditionQuery.java @@ -42,6 +42,7 @@ import com.baidu.hugegraph.structure.HugeProperty; import com.baidu.hugegraph.type.HugeType; import com.baidu.hugegraph.type.define.HugeKeys; +import com.baidu.hugegraph.util.CollectionUtil; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.InsertionOrderUtil; import com.baidu.hugegraph.util.LongEncoding; @@ -217,23 +218,65 @@ public Relation relation(Id key){ @Watched public T condition(Object key) { - List values = new ArrayList<>(); + List valuesEQ = InsertionOrderUtil.newList(); + List valuesIN = InsertionOrderUtil.newList(); for (Condition c : this.conditions) { if (c.isRelation()) { Condition.Relation r = (Condition.Relation) c; - if (r.key().equals(key) && (r.relation() == RelationType.EQ || - r.relation() == RelationType.IN)) { - values.add(r.value()); + if (r.key().equals(key)) { + if (r.relation() == RelationType.EQ) { + valuesEQ.add(r.value()); + } else if (r.relation() == RelationType.IN) { + Object value = r.value(); + assert value instanceof List; + valuesIN.add(value); + } } } } - if (values.isEmpty()) { + if (valuesEQ.isEmpty() && valuesIN.isEmpty()) { return null; } - E.checkState(values.size() == 1, - "Illegal key '%s' with more than one value", key); + if (valuesEQ.size() == 1 && valuesIN.size() == 0) { + @SuppressWarnings("unchecked") + T value = (T) valuesEQ.get(0); + return value; + } + if (valuesEQ.size() == 0 && valuesIN.size() == 1) { + @SuppressWarnings("unchecked") + T value = (T) valuesIN.get(0); + return value; + } + + Set intersectValues = InsertionOrderUtil.newSet(); + for (Object value : valuesEQ) { + List valueAsList = ImmutableList.of(value); + if (intersectValues.isEmpty()) { + intersectValues.addAll(valueAsList); + } else { + CollectionUtil.intersectWithModify(intersectValues, + valueAsList); + } + } + for (Object value : valuesIN) { + @SuppressWarnings("unchecked") + List valueAsList = (List) value; + if (intersectValues.isEmpty()) { + intersectValues.addAll(valueAsList); + } else { + CollectionUtil.intersectWithModify(intersectValues, + valueAsList); + } + } + + if (intersectValues.size() == 0) { + return null; + } + E.checkState(intersectValues.size() == 1, + "Illegal key '%s' with more than one value: %s", + key, intersectValues); @SuppressWarnings("unchecked") - T value = (T) values.get(0); + T value = (T) intersectValues.iterator().next(); return value; } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/optimize/HugeVertexStep.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/optimize/HugeVertexStep.java index 828528baa5..2468c1f406 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/optimize/HugeVertexStep.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/traversal/optimize/HugeVertexStep.java @@ -144,7 +144,7 @@ protected ConditionQuery constructEdgesQuery( ConditionQuery query = GraphTransaction.constructEdgesQuery( vertex, direction, edgeLabels); // Query by sort-keys - if (withEdgeCond && edgeLabels.length > 0) { + if (withEdgeCond && edgeLabels.length == 1) { TraversalUtil.fillConditionQuery(query, this.hasContainers, graph); if (!GraphTransaction.matchPartialEdgeSortKeys(query, graph)) { // Can't query by sysprop and by index (HugeGraph-749) diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java index b08989e58b..51147737b4 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/EdgeCoreTest.java @@ -3581,12 +3581,12 @@ public void testQueryOutEdgesOfVertexBySortkeyWithRange() { Assert.assertEquals(3, edges.size()); edges = graph.traversal().V(v1).outE("call") - .has("calltime", P.between("2017-5-2","2017-5-4")) + .has("calltime", P.between("2017-5-2", "2017-5-4")) .toList(); Assert.assertEquals(5, edges.size()); edges = graph.traversal().V(v1).outE("call") - .has("calltime", P.between("2017-5-2","2017-5-4")) + .has("calltime", P.between("2017-5-2", "2017-5-4")) .where(__.not(__.otherV().hasId((v10086.id())))) .toList(); Assert.assertEquals(3, edges.size()); @@ -4549,6 +4549,33 @@ public void testQueryInEdgesOfVertexByLabelAndFilter() { Assert.assertEquals(1, edges.size()); } + @Test + public void testQueryInEdgesOfVertexByLabels() { + HugeGraph graph = graph(); + init18Edges(); + + long size; + size = graph.traversal().V().outE("created", "authored", "look") + .hasLabel("authored", "created") + .count().next(); + Assert.assertEquals(5L, size); + + size = graph.traversal().V().outE("created", "authored", "look") + .hasLabel("authored", "friend") + .count().next(); + Assert.assertEquals(3L, size); + + size = graph.traversal().V().outE("created") + .hasLabel("authored", "created") + .count().next(); + Assert.assertEquals(2L, size); + + size = graph.traversal().V().inE("created", "authored", "look") + .has("score", 3) + .count().next(); + Assert.assertEquals(3L, size); + } + @Test public void testQueryInEdgesOfVertexBySortkey() { HugeGraph graph = graph(); @@ -7242,7 +7269,7 @@ public void testAddEdgeWithCollectionIndex() { List edges = graph.traversal().E() - .has("related","tags", + .has("related", "tags", ConditionP.contains("gremlin")) .toList();