From 98fef9a4f248cbce4f856da1760cca75b12f937b Mon Sep 17 00:00:00 2001 From: contrueCT Date: Sun, 12 Apr 2026 15:53:35 +0800 Subject: [PATCH 1/5] fix: support boolean range predicates in condition query --- .../hugegraph/backend/query/Condition.java | 18 +++++++- .../backend/query/ConditionQueryFlatten.java | 3 ++ .../apache/hugegraph/core/EdgeCoreTest.java | 42 ++++++++++++++++++ .../unit/core/ConditionQueryFlattenTest.java | 43 +++++++++++++++++++ .../hugegraph/unit/core/ConditionTest.java | 26 +++++++++++ .../org/apache/hugegraph/query/Condition.java | 18 +++++++- 6 files changed, 148 insertions(+), 2 deletions(-) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Condition.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Condition.java index 09e223e4ca..e65179df55 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Condition.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/Condition.java @@ -195,7 +195,7 @@ private static boolean equals(final Object first, * * @param first is actual value, might be Number/Date or String, It is * probably that the `first` is serialized to String. - * @param second is value in query condition, must be Number/Date + * @param second is value in query condition, must be Number/Date/Boolean * @return the value 0 if first is numerically equal to second; * a value less than 0 if first is numerically less than * second; and a value greater than 0 if first is @@ -208,6 +208,8 @@ private static int compare(final Object first, final Object second) { (Number) second); } else if (second instanceof Date) { return compareDate(first, (Date) second); + } else if (second instanceof Boolean) { + return compareBoolean(first, (Boolean) second); } throw new IllegalArgumentException(String.format( @@ -230,6 +232,20 @@ private static int compareDate(Object first, Date second) { second, second.getClass().getSimpleName())); } + private static int compareBoolean(Object first, Boolean second) { + if (first == null) { + first = false; + } + if (first instanceof Boolean) { + return Boolean.compare((Boolean) first, second); + } + + throw new IllegalArgumentException(String.format( + "Can't compare between %s(%s) and %s(%s)", + first, first.getClass().getSimpleName(), + second, second.getClass().getSimpleName())); + } + private void checkBaseType(Object value, Class clazz) { if (!clazz.isInstance(value)) { String valueClass = value == null ? "null" : diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java index 83af41b008..5209178ba5 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java @@ -507,6 +507,9 @@ private static int compare(Relation first, Relation second) { return NumericUtil.compareNumber(firstValue, (Number) secondValue); } else if (firstValue instanceof Date && secondValue instanceof Date) { return ((Date) firstValue).compareTo((Date) secondValue); + } else if (firstValue instanceof Boolean && + secondValue instanceof Boolean) { + return Boolean.compare((Boolean) firstValue, (Boolean) secondValue); } else { throw new IllegalArgumentException(String.format("Can't compare between %s and %s", first, second)); diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java index 265d408742..648b6dffd5 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java @@ -7117,6 +7117,48 @@ public void testQueryEdgeWithNullablePropertyInCompositeIndex() { Assert.assertEquals(1, (int) el.get(0).value("id")); } + @Test + public void testQueryEdgeByBooleanRangePredicate() { + HugeGraph graph = graph(); + initStrikeIndex(); + + Vertex louise = graph.addVertex(T.label, "person", "name", "Louise", + "city", "Beijing", "age", 21); + Vertex sean = graph.addVertex(T.label, "person", "name", "Sean", + "city", "Beijing", "age", 23); + long current = System.currentTimeMillis(); + louise.addEdge("strike", sean, "id", 1, + "timestamp", current, "place", "park", + "tool", "shovel", "reason", "jeer", + "arrested", false); + louise.addEdge("strike", sean, "id", 2, + "timestamp", current + 1, "place", "street", + "tool", "shovel", "reason", "jeer", + "arrested", true); + + List hasEdges = graph.traversal().E() + .has("arrested", P.lt(true)) + .toList(); + Assert.assertEquals(1, hasEdges.size()); + Assert.assertEquals(1, (int) hasEdges.get(0).value("id")); + + List whereEdges = graph.traversal().E() + .where(__.has("arrested", P.lt(true))) + .toList(); + Assert.assertEquals(1, whereEdges.size()); + Assert.assertEquals(1, (int) whereEdges.get(0).value("id")); + + List matchEdges = graph.traversal().E() + .as("e") + .match(__.as("e") + .has("arrested", P.lt(true))) + .select("e") + .dedup() + .toList(); + Assert.assertEquals(1, matchEdges.size()); + Assert.assertEquals(1, (int) matchEdges.get(0).value("id")); + } + @Test public void testQueryEdgeByPage() { Assume.assumeTrue("Not support paging", diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionQueryFlattenTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionQueryFlattenTest.java index 627dcb29aa..dbe5506480 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionQueryFlattenTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionQueryFlattenTest.java @@ -256,5 +256,48 @@ public void testFlattenWithNotIn() { Collection actual = queries.iterator().next().conditions(); Assert.assertEquals(expect, actual); } + + @Test + public void testFlattenWithBooleanRangeUpperBound() { + Id key = IdGenerator.of("c1"); + + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + query.query(Condition.lt(key, true)); + query.query(Condition.lt(key, false)); + + List queries = ConditionQueryFlatten.flatten(query); + Assert.assertEquals(1, queries.size()); + + Collection actual = queries.iterator().next().conditions(); + Assert.assertEquals(ImmutableList.of(Condition.lt(key, false)), actual); + } + + @Test + public void testFlattenWithBooleanRangeWindow() { + Id key = IdGenerator.of("c1"); + + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + query.query(Condition.gte(key, false)); + query.query(Condition.lt(key, true)); + + List queries = ConditionQueryFlatten.flatten(query); + Assert.assertEquals(1, queries.size()); + + Collection actual = queries.iterator().next().conditions(); + Assert.assertEquals(ImmutableList.of(Condition.gte(key, false), + Condition.lt(key, true)), actual); + } + + @Test + public void testFlattenWithConflictingBooleanRange() { + Id key = IdGenerator.of("c1"); + + ConditionQuery query = new ConditionQuery(HugeType.VERTEX); + query.query(Condition.gt(key, false)); + query.query(Condition.lt(key, true)); + + List queries = ConditionQueryFlatten.flatten(query); + Assert.assertEquals(0, queries.size()); + } } diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionTest.java index e333c7a98b..485c3d6c23 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/ConditionTest.java @@ -293,6 +293,32 @@ public void testConditionLte() { }); } + @Test + public void testConditionBooleanRange() { + Condition lt = Condition.lt(HugeKeys.ID, true); + Assert.assertTrue(lt.test(false)); + Assert.assertFalse(lt.test(true)); + + Condition lte = Condition.lte(HugeKeys.ID, false); + Assert.assertTrue(lte.test(false)); + Assert.assertFalse(lte.test(true)); + + Condition gt = Condition.gt(HugeKeys.ID, false); + Assert.assertTrue(gt.test(true)); + Assert.assertFalse(gt.test(false)); + + Condition gte = Condition.gte(HugeKeys.ID, true); + Assert.assertTrue(gte.test(true)); + Assert.assertFalse(gte.test(false)); + + Assert.assertThrows(IllegalArgumentException.class, () -> { + Condition.lt(HugeKeys.ID, true).test(1); + }, e -> { + String err = "Can't compare between 1(Integer) and true(Boolean)"; + Assert.assertEquals(err, e.getMessage()); + }); + } + @Test public void testConditionNeq() { Condition c1 = Condition.neq(HugeKeys.ID, 123); diff --git a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Condition.java b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Condition.java index 5c7d3e221c..0b97c95c8a 100644 --- a/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Condition.java +++ b/hugegraph-struct/src/main/java/org/apache/hugegraph/query/Condition.java @@ -437,7 +437,7 @@ private static boolean equals(final Object first, * * @param first is actual value, might be Number/Date or String, It is * probably that the `first` is serialized to String. - * @param second is value in query condition, must be Number/Date + * @param second is value in query condition, must be Number/Date/Boolean * @return the value 0 if first is numerically equal to second; * a value less than 0 if first is numerically less than * second; and a value greater than 0 if first is @@ -450,6 +450,8 @@ private static int compare(final Object first, final Object second) { (Number) second); } else if (second instanceof Date) { return compareDate(first, (Date) second); + } else if (second instanceof Boolean) { + return compareBoolean(first, (Boolean) second); } throw new IllegalArgumentException(String.format( @@ -472,6 +474,20 @@ private static int compareDate(Object first, Date second) { second, second.getClass().getSimpleName())); } + private static int compareBoolean(Object first, Boolean second) { + if (first == null) { + first = false; + } + if (first instanceof Boolean) { + return Boolean.compare((Boolean) first, second); + } + + throw new IllegalArgumentException(String.format( + "Can't compare between %s(%s) and %s(%s)", + first, first.getClass().getSimpleName(), + second, second.getClass().getSimpleName())); + } + public static List tokenize(String str) { final ArrayList tokens = new ArrayList<>(); int previous = 0; From dc441b64d756f2daff94fcec2ac4fe336839b7e9 Mon Sep 17 00:00:00 2001 From: contrueCT Date: Sun, 12 Apr 2026 15:58:26 +0800 Subject: [PATCH 2/5] test: cover boolean range query edge cases --- .../backend/query/ConditionQueryFlatten.java | 23 ++++++++++++++++--- .../apache/hugegraph/core/EdgeCoreTest.java | 2 ++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java index 5209178ba5..8b9b7cb1d8 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java @@ -427,9 +427,26 @@ private static boolean validRange(Relation low, Relation high) { if (low == null || high == null) { return true; } - return compare(low, high) < 0 || compare(low, high) == 0 && - low.relation() == Condition.RelationType.GTE && - high.relation() == Condition.RelationType.LTE; + int compared = compare(low, high); + if (compared > 0) { + return false; + } + if (compared == 0) { + return low.relation() == Condition.RelationType.GTE && + high.relation() == Condition.RelationType.LTE; + } + return !emptyBooleanRange(low, high); + } + + private static boolean emptyBooleanRange(Relation low, Relation high) { + if (!(low.value() instanceof Boolean) || + !(high.value() instanceof Boolean)) { + return false; + } + return Boolean.FALSE.equals(low.value()) && + Boolean.TRUE.equals(high.value()) && + low.relation() == Condition.RelationType.GT && + high.relation() == Condition.RelationType.LT; } private static boolean validEq(Relation eq, Relation low, Relation high) { diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java index 648b6dffd5..1c15969449 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java @@ -7121,6 +7121,8 @@ public void testQueryEdgeWithNullablePropertyInCompositeIndex() { public void testQueryEdgeByBooleanRangePredicate() { HugeGraph graph = graph(); initStrikeIndex(); + graph.schema().indexLabel("strikeByArrested").onE("strike").secondary() + .by("arrested").create(); Vertex louise = graph.addVertex(T.label, "person", "name", "Louise", "city", "Beijing", "age", 21); From 4cd2049221918cb2986d8197ef2312f81a2a751b Mon Sep 17 00:00:00 2001 From: contrueCT Date: Sun, 12 Apr 2026 16:06:49 +0800 Subject: [PATCH 3/5] fix(test): align boolean range regression coverage --- .../backend/query/ConditionQueryFlatten.java | 2 +- .../apache/hugegraph/core/EdgeCoreTest.java | 18 +++++------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java index 8b9b7cb1d8..3208c0549c 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/query/ConditionQueryFlatten.java @@ -265,7 +265,7 @@ private static List flattenRelations(ConditionQuery query) { cq.query(nonRelations); return ImmutableList.of(cq); } - return ImmutableList.of(query); + return ImmutableList.of(); } private static Relations optimizeRelations(Relations relations) { diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java index 1c15969449..c742136a6a 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java @@ -7121,8 +7121,6 @@ public void testQueryEdgeWithNullablePropertyInCompositeIndex() { public void testQueryEdgeByBooleanRangePredicate() { HugeGraph graph = graph(); initStrikeIndex(); - graph.schema().indexLabel("strikeByArrested").onE("strike").secondary() - .by("arrested").create(); Vertex louise = graph.addVertex(T.label, "person", "name", "Louise", "city", "Beijing", "age", 21); @@ -7138,12 +7136,6 @@ public void testQueryEdgeByBooleanRangePredicate() { "tool", "shovel", "reason", "jeer", "arrested", true); - List hasEdges = graph.traversal().E() - .has("arrested", P.lt(true)) - .toList(); - Assert.assertEquals(1, hasEdges.size()); - Assert.assertEquals(1, (int) hasEdges.get(0).value("id")); - List whereEdges = graph.traversal().E() .where(__.has("arrested", P.lt(true))) .toList(); @@ -7151,11 +7143,11 @@ public void testQueryEdgeByBooleanRangePredicate() { Assert.assertEquals(1, (int) whereEdges.get(0).value("id")); List matchEdges = graph.traversal().E() - .as("e") - .match(__.as("e") - .has("arrested", P.lt(true))) - .select("e") - .dedup() + .match(__.as("start") + .where(__.has("arrested", + P.lt(true))) + .as("matched")) + .select("matched") .toList(); Assert.assertEquals(1, matchEdges.size()); Assert.assertEquals(1, (int) matchEdges.get(0).value("id")); From d92050ff93133131518433ae70afd04b96a37605 Mon Sep 17 00:00:00 2001 From: contrueCT Date: Sun, 12 Apr 2026 16:14:43 +0800 Subject: [PATCH 4/5] fix(core): normalize boolean range predicates --- .../traversal/optimize/TraversalUtil.java | 48 ++++++++++++++++--- .../apache/hugegraph/core/EdgeCoreTest.java | 2 + 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java index 11a5c0cee4..c61504063e 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java @@ -46,6 +46,7 @@ import org.apache.hugegraph.structure.HugeElement; import org.apache.hugegraph.structure.HugeProperty; import org.apache.hugegraph.type.HugeType; +import org.apache.hugegraph.type.define.DataType; import org.apache.hugegraph.type.define.Directions; import org.apache.hugegraph.type.define.HugeKeys; import org.apache.hugegraph.util.CollectionUtil; @@ -419,9 +420,9 @@ public static Condition convOr(HugeGraph graph, return cond; } - private static Condition.Relation convCompare2Relation(HugeGraph graph, - HugeType type, - HasContainer has) { + private static Condition convCompare2Relation(HugeGraph graph, + HugeType type, + HasContainer has) { assert type.isGraph(); BiPredicate bp = has.getPredicate().getBiPredicate(); assert bp instanceof Compare; @@ -459,9 +460,9 @@ private static Condition.Relation convCompare2SyspropRelation(HugeGraph graph, } } - private static Condition.Relation convCompare2UserpropRelation(HugeGraph graph, - HugeType type, - HasContainer has) { + private static Condition convCompare2UserpropRelation(HugeGraph graph, + HugeType type, + HasContainer has) { BiPredicate bp = has.getPredicate().getBiPredicate(); assert bp instanceof Compare; @@ -469,6 +470,11 @@ private static Condition.Relation convCompare2UserpropRelation(HugeGraph graph, PropertyKey pkey = graph.propertyKey(key); Id pkeyId = pkey.id(); Object value = validPropertyValue(has.getValue(), pkey); + if (pkey.dataType() == DataType.BOOLEAN && + value instanceof Boolean) { + return convCompare2BooleanUserpropRelation((Compare) bp, pkeyId, + (Boolean) value); + } switch ((Compare) bp) { case eq: @@ -488,6 +494,36 @@ private static Condition.Relation convCompare2UserpropRelation(HugeGraph graph, } } + private static Condition convCompare2BooleanUserpropRelation(Compare compare, + Id key, + Boolean value) { + switch (compare) { + case eq: + return Condition.eq(key, value); + case neq: + return Condition.neq(key, value); + case gt: + return value ? impossibleBooleanCondition(key) : + Condition.eq(key, true); + case gte: + return value ? Condition.eq(key, true) : + Condition.in(key, ImmutableList.of(false, true)); + case lt: + return value ? Condition.eq(key, false) : + impossibleBooleanCondition(key); + case lte: + return value ? Condition.in(key, ImmutableList.of(false, true)) : + Condition.eq(key, false); + default: + throw new AssertionError(compare); + } + } + + private static Condition impossibleBooleanCondition(Id key) { + return Condition.and(Condition.eq(key, false), + Condition.eq(key, true)); + } + private static Condition convRelationType2Relation(HugeGraph graph, HugeType type, HasContainer has) { diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java index c742136a6a..b71ac5e862 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java @@ -7121,6 +7121,8 @@ public void testQueryEdgeWithNullablePropertyInCompositeIndex() { public void testQueryEdgeByBooleanRangePredicate() { HugeGraph graph = graph(); initStrikeIndex(); + graph.schema().indexLabel("strikeByArrested").onE("strike").secondary() + .by("arrested").create(); Vertex louise = graph.addVertex(T.label, "person", "name", "Louise", "city", "Beijing", "age", 21); From a07f43faf3f29d0a29433be39a2d57693c87fd12 Mon Sep 17 00:00:00 2001 From: contrueCT Date: Sun, 12 Apr 2026 16:22:01 +0800 Subject: [PATCH 5/5] test(core): expand boolean range edge coverage --- .../apache/hugegraph/core/EdgeCoreTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java index b71ac5e862..efa3ded95f 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/EdgeCoreTest.java @@ -7138,6 +7138,12 @@ public void testQueryEdgeByBooleanRangePredicate() { "tool", "shovel", "reason", "jeer", "arrested", true); + List hasLtEdges = graph.traversal().E() + .has("arrested", P.lt(true)) + .toList(); + Assert.assertEquals(1, hasLtEdges.size()); + Assert.assertEquals(1, (int) hasLtEdges.get(0).value("id")); + List whereEdges = graph.traversal().E() .where(__.has("arrested", P.lt(true))) .toList(); @@ -7153,6 +7159,51 @@ public void testQueryEdgeByBooleanRangePredicate() { .toList(); Assert.assertEquals(1, matchEdges.size()); Assert.assertEquals(1, (int) matchEdges.get(0).value("id")); + + List hasLteFalseEdges = graph.traversal().E() + .has("arrested", P.lte(false)) + .toList(); + Assert.assertEquals(1, hasLteFalseEdges.size()); + Assert.assertEquals(1, (int) hasLteFalseEdges.get(0).value("id")); + + List hasGtFalseEdges = graph.traversal().E() + .has("arrested", P.gt(false)) + .toList(); + Assert.assertEquals(1, hasGtFalseEdges.size()); + Assert.assertEquals(2, (int) hasGtFalseEdges.get(0).value("id")); + + List hasGteTrueEdges = graph.traversal().E() + .has("arrested", P.gte(true)) + .toList(); + Assert.assertEquals(1, hasGteTrueEdges.size()); + Assert.assertEquals(2, (int) hasGteTrueEdges.get(0).value("id")); + + List hasGteFalseEdges = graph.traversal().E() + .has("arrested", P.gte(false)) + .toList(); + Assert.assertEquals(2, hasGteFalseEdges.size()); + Set gteFalseIds = new HashSet<>(); + for (Edge edge : hasGteFalseEdges) { + gteFalseIds.add(edge.value("id")); + } + Assert.assertEquals(ImmutableSet.of(1, 2), gteFalseIds); + + List hasLteTrueEdges = graph.traversal().E() + .has("arrested", P.lte(true)) + .toList(); + Assert.assertEquals(2, hasLteTrueEdges.size()); + Set lteTrueIds = new HashSet<>(); + for (Edge edge : hasLteTrueEdges) { + lteTrueIds.add(edge.value("id")); + } + Assert.assertEquals(ImmutableSet.of(1, 2), lteTrueIds); + + Assert.assertEquals(0, graph.traversal().E() + .has("arrested", P.lt(false)) + .toList().size()); + Assert.assertEquals(0, graph.traversal().E() + .has("arrested", P.gt(true)) + .toList().size()); } @Test