|
154 | 154 | import static org.janusgraph.testutil.JanusGraphAssert.assertNoBackendHit; |
155 | 155 | import static org.janusgraph.testutil.JanusGraphAssert.assertNotEmpty; |
156 | 156 | import static org.janusgraph.testutil.JanusGraphAssert.assertTraversal; |
| 157 | +import static org.janusgraph.testutil.JanusGraphAssert.assertTraversalAndIndexUsage; |
157 | 158 | import static org.junit.jupiter.api.Assertions.assertEquals; |
158 | 159 | import static org.junit.jupiter.api.Assertions.assertFalse; |
159 | 160 | import static org.junit.jupiter.api.Assertions.assertNotNull; |
@@ -186,16 +187,18 @@ public abstract class JanusGraphIndexTest extends JanusGraphBaseTest { |
186 | 187 | public final boolean supportsGeoPoint; |
187 | 188 | public final boolean supportsNumeric; |
188 | 189 | public final boolean supportsText; |
| 190 | + public final boolean supportsOrderingListProperty; |
189 | 191 |
|
190 | 192 | public IndexFeatures indexFeatures; |
191 | 193 |
|
192 | 194 | private static final Logger log = |
193 | 195 | LoggerFactory.getLogger(JanusGraphIndexTest.class); |
194 | 196 |
|
195 | | - protected JanusGraphIndexTest(boolean supportsGeoPoint, boolean supportsNumeric, boolean supportsText) { |
| 197 | + protected JanusGraphIndexTest(boolean supportsGeoPoint, boolean supportsNumeric, boolean supportsText, boolean supportsOrderingListProperty) { |
196 | 198 | this.supportsGeoPoint = supportsGeoPoint; |
197 | 199 | this.supportsNumeric = supportsNumeric; |
198 | 200 | this.supportsText = supportsText; |
| 201 | + this.supportsOrderingListProperty = supportsOrderingListProperty; |
199 | 202 | } |
200 | 203 |
|
201 | 204 | protected String[] getIndexBackends() { |
@@ -4434,4 +4437,189 @@ public void testGetIndexInfo() throws DecoderException { |
4434 | 4437 | assertEquals(1, indexInfo.getCompositeIndexType().getInlineFieldKeys().length); |
4435 | 4438 | assertEquals("id", indexInfo.getCompositeIndexType().getInlineFieldKeys()[0]); |
4436 | 4439 | } |
| 4440 | + |
| 4441 | + @Test |
| 4442 | + public void testOrderingListProperty() { |
| 4443 | + PropertyKey name1 = mgmt.makePropertyKey("name1").dataType(String.class).cardinality(Cardinality.SINGLE) |
| 4444 | + .make(); |
| 4445 | + PropertyKey name2 = mgmt.makePropertyKey("name2").dataType(String.class).cardinality(Cardinality.LIST) |
| 4446 | + .make(); |
| 4447 | + PropertyKey gender = mgmt.makePropertyKey("gender").dataType(String.class).cardinality(Cardinality.SINGLE).make(); |
| 4448 | + PropertyKey age1 = mgmt.makePropertyKey("age1").dataType(Double.class).cardinality(Cardinality.SINGLE).make(); |
| 4449 | + PropertyKey age2 = mgmt.makePropertyKey("age2").dataType(Double.class).cardinality(Cardinality.LIST).make(); |
| 4450 | + PropertyKey birth1 = mgmt.makePropertyKey("birth1").dataType(Date.class).cardinality(Cardinality.SINGLE).make(); |
| 4451 | + PropertyKey birth2 = mgmt.makePropertyKey("birth2").dataType(Date.class).cardinality(Cardinality.LIST).make(); |
| 4452 | + |
| 4453 | + mgmt.buildIndex("listPropertyOrdering", Vertex.class) |
| 4454 | + .addKey(name1, Mapping.STRING.asParameter()) |
| 4455 | + .addKey(name2, Mapping.STRING.asParameter()) |
| 4456 | + .addKey(gender, Mapping.STRING.asParameter()) |
| 4457 | + .addKey(age1) |
| 4458 | + .addKey(age2) |
| 4459 | + .addKey(birth1) |
| 4460 | + .addKey(birth2) |
| 4461 | + .buildMixedIndex(INDEX); |
| 4462 | + finishSchema(); |
| 4463 | + |
| 4464 | + Vertex v1 = tx.addVertex("gender", "male", "name1", "value1", "name2", "value1", "age1", 1, "age2", 1, "birth1", "2010-01-01T00:00:00", "birth2", "2010-01-01T00:00:00"); |
| 4465 | + Vertex v2 = tx.addVertex("gender", "female", "name1", "value2", "name2", "value2", "age1", 2, "age2", 2, "birth1", "2011-01-01T00:00:00", "birth2", "2011-01-01T00:00:00"); |
| 4466 | + Vertex v3 = tx.addVertex("gender", "male", "name1", "value3", "name2", "value3", "name2", "value8", "age1", 3, "age2", 3, "birth1", "2012-01-01T00:00:00", "birth2", "2012-01-01T00:00:00"); |
| 4467 | + Vertex v4 = tx.addVertex("gender", "female", "name1", "value4", "name2", "value4", "name2", "value7", "age1", 4, "age2", 4, "birth1", "2013-01-01T00:00:00", "birth2", "2013-01-01T00:00:00"); |
| 4468 | + Vertex v5 = tx.addVertex("gender", "male", "name1", "value5", "name2", "value5", "age1", 5, "age2", 5, "birth1", "2014-01-01T00:00:00", "birth2", "2014-01-01T00:00:00"); |
| 4469 | + Vertex v6 = tx.addVertex("gender", "female", "name1", "value6", "name2", "value6", "age1", 6, "age2", 6, "birth1", "2015-01-01T00:00:00", "birth2", "2015-01-01T00:00:00"); |
| 4470 | + tx.commit(); |
| 4471 | + |
| 4472 | + clopen(option(FORCE_INDEX_USAGE), false); |
| 4473 | + |
| 4474 | + final GraphTraversalSource g = tx.traversal(); |
| 4475 | + org.apache.tinkerpop.gremlin.process.traversal.Order ORDER_DESC = org.apache.tinkerpop.gremlin.process.traversal.Order.desc; |
| 4476 | + |
| 4477 | + // ordering without using index on SINGLE cardinality property |
| 4478 | + Supplier<GraphTraversal<?, Vertex>> tFullscanSingle = () -> g.V().order().by("name1"); |
| 4479 | + assertTraversalAndIndexUsage( |
| 4480 | + Arrays.asList( |
| 4481 | + "query=[]", |
| 4482 | + "_fullscan=true" |
| 4483 | + ), |
| 4484 | + tFullscanSingle, v1, v2, v3, v4, v5, v6 |
| 4485 | + ); |
| 4486 | + |
| 4487 | + // ordering without using index on LIST cardinality property with multiple values |
| 4488 | + // throws IllegalStateException with message "Multiple properties exist for the provided key, use Vertex.properties(name2)" |
| 4489 | + Exception exception = assertThrows(IllegalStateException.class, () -> { |
| 4490 | + g.V().order().by("name2").toList(); |
| 4491 | + }); |
| 4492 | + assertTrue(exception.getMessage().contains("Multiple properties exist for the provided key, use Vertex.properties(name2)")); |
| 4493 | + |
| 4494 | + /////////////////////////////////////////////////// |
| 4495 | + // ordering SINGLE cardinality properties |
| 4496 | + // ordering SINGLE cardinality String property |
| 4497 | + Supplier<GraphTraversal<?, Vertex>> tSingleString = () -> g.V().has("name1").order().by("name1", ORDER_DESC); |
| 4498 | + assertTraversalAndIndexUsage( |
| 4499 | + Arrays.asList( |
| 4500 | + "_condition=(name1 <> null)", |
| 4501 | + "_query=[(name1 <> null)][DESC(name1)]:listPropertyOrdering" |
| 4502 | + ), |
| 4503 | + tSingleString, v6, v5, v4, v3, v2, v1 |
| 4504 | + ); |
| 4505 | + |
| 4506 | + // ordering SINGLE cardinality Double property |
| 4507 | + Supplier<GraphTraversal<?, Vertex>> tSingleDouble = () -> g.V().has("age1").order().by("age1", ORDER_DESC); |
| 4508 | + assertTraversalAndIndexUsage( |
| 4509 | + Arrays.asList( |
| 4510 | + "_condition=(age1 <> null)", |
| 4511 | + "_query=[(age1 <> null)][DESC(age1)]:listPropertyOrdering" |
| 4512 | + ), |
| 4513 | + tSingleDouble, v6, v5, v4, v3, v2, v1 |
| 4514 | + ); |
| 4515 | + |
| 4516 | + // ordering SINGLE cardinality Date property |
| 4517 | + Supplier<GraphTraversal<?, Vertex>> tSingleDate = () -> g.V().has("birth1").order().by("birth1", ORDER_DESC); |
| 4518 | + assertTraversalAndIndexUsage( |
| 4519 | + Arrays.asList( |
| 4520 | + "_condition=(birth1 <> null)", |
| 4521 | + "_query=[(birth1 <> null)][DESC(birth1)]:listPropertyOrdering" |
| 4522 | + ), |
| 4523 | + tSingleDate, v6, v5, v4, v3, v2, v1 |
| 4524 | + ); |
| 4525 | + |
| 4526 | + ///////////////////////////////////////////////// |
| 4527 | + // ordering SINGLE cardinality properties with filtering |
| 4528 | + // ordering SINGLE cardinality String property |
| 4529 | + Supplier<GraphTraversal<?, Vertex>> tSingleStringFilter = () -> g.V().has("gender", "female").has("name1").order().by("name1", ORDER_DESC); |
| 4530 | + assertTraversalAndIndexUsage( |
| 4531 | + Arrays.asList( |
| 4532 | + "_condition=(gender = female AND name1 <> null)", |
| 4533 | + "_query=[(gender = female AND name1 <> null)][DESC(name1)]:listPropertyOrdering" |
| 4534 | + ), |
| 4535 | + tSingleStringFilter, v6, v4, v2 |
| 4536 | + ); |
| 4537 | + |
| 4538 | + // ordering SINGLE cardinality Double property |
| 4539 | + Supplier<GraphTraversal<?, Vertex>> tSingleDoubleFilter = () -> g.V().has("gender", "female").has("age1").order().by("age1", ORDER_DESC); |
| 4540 | + assertTraversalAndIndexUsage( |
| 4541 | + Arrays.asList( |
| 4542 | + "_condition=(gender = female AND age1 <> null)", |
| 4543 | + "_query=[(gender = female AND age1 <> null)][DESC(age1)]:listPropertyOrdering" |
| 4544 | + ), |
| 4545 | + tSingleDoubleFilter, v6, v4, v2 |
| 4546 | + ); |
| 4547 | + |
| 4548 | + // ordering SINGLE cardinality Date property |
| 4549 | + Supplier<GraphTraversal<?, Vertex>> tSingleDateFilter = () -> g.V().has("gender", "female").has("birth1").order().by("birth1", ORDER_DESC); |
| 4550 | + assertTraversalAndIndexUsage( |
| 4551 | + Arrays.asList( |
| 4552 | + "_condition=(gender = female AND birth1 <> null)", |
| 4553 | + "_query=[(gender = female AND birth1 <> null)][DESC(birth1)]:listPropertyOrdering" |
| 4554 | + ), |
| 4555 | + tSingleDateFilter, v6, v4, v2 |
| 4556 | + ); |
| 4557 | + |
| 4558 | + // certain mixed index backend specific part since Lucene does not support ordering for list properties |
| 4559 | + if (supportsOrderingListProperty) { |
| 4560 | + /////////////////////////////////////////////////// |
| 4561 | + // ordering LIST cardinality properties |
| 4562 | + // ordering LIST cardinality String property |
| 4563 | + Supplier<GraphTraversal<?, Vertex>> tListString = () -> g.V().has("name2").order().by("name2", ORDER_DESC); |
| 4564 | + assertTraversalAndIndexUsage( |
| 4565 | + Arrays.asList( |
| 4566 | + "_condition=(name2 <> null)", |
| 4567 | + "_query=[(name2 <> null)][DESC(name2)]:listPropertyOrdering" |
| 4568 | + ), |
| 4569 | + tListString, v3, v4, v6, v5, v2, v1 |
| 4570 | + ); |
| 4571 | + |
| 4572 | + // ordering LIST cardinality Double property |
| 4573 | + Supplier<GraphTraversal<?, Vertex>> tListDouble = () -> g.V().has("age2").order().by("age2", ORDER_DESC); |
| 4574 | + assertTraversalAndIndexUsage( |
| 4575 | + Arrays.asList( |
| 4576 | + "_condition=(age2 <> null)", |
| 4577 | + "_query=[(age2 <> null)][DESC(age2)]:listPropertyOrdering" |
| 4578 | + ), |
| 4579 | + tListDouble, v6, v5, v4, v3, v2, v1 |
| 4580 | + ); |
| 4581 | + |
| 4582 | + // ordering LIST cardinality Date property |
| 4583 | + Supplier<GraphTraversal<?, Vertex>> tListDate = () -> g.V().has("birth2").order().by("birth2", ORDER_DESC); |
| 4584 | + assertTraversalAndIndexUsage( |
| 4585 | + Arrays.asList( |
| 4586 | + "_condition=(birth2 <> null)", |
| 4587 | + "_query=[(birth2 <> null)][DESC(birth2)]:listPropertyOrdering" |
| 4588 | + ), |
| 4589 | + tListDate, v6, v5, v4, v3, v2, v1 |
| 4590 | + ); |
| 4591 | + |
| 4592 | + ///////////////////////////////////////////////// |
| 4593 | + // ordering LIST cardinality properties with filtering |
| 4594 | + // ordering LIST cardinality String property |
| 4595 | + Supplier<GraphTraversal<?, Vertex>> tListStringFilter = () -> g.V().has("gender", "female").has("name2").order().by("name2", ORDER_DESC); |
| 4596 | + assertTraversalAndIndexUsage( |
| 4597 | + Arrays.asList( |
| 4598 | + "_condition=(gender = female AND name2 <> null)", |
| 4599 | + "_query=[(gender = female AND name2 <> null)][DESC(name2)]:listPropertyOrdering" |
| 4600 | + ), |
| 4601 | + tListStringFilter, v4, v6, v2 |
| 4602 | + ); |
| 4603 | + |
| 4604 | + // ordering LIST cardinality Double property |
| 4605 | + Supplier<GraphTraversal<?, Vertex>> tListDoubleFilter = () -> g.V().has("gender", "female").has("age2").order().by("age2", ORDER_DESC); |
| 4606 | + assertTraversalAndIndexUsage( |
| 4607 | + Arrays.asList( |
| 4608 | + "_condition=(gender = female AND age2 <> null)", |
| 4609 | + "_query=[(gender = female AND age2 <> null)][DESC(age2)]:listPropertyOrdering" |
| 4610 | + ), |
| 4611 | + tListDoubleFilter, v6, v4, v2 |
| 4612 | + ); |
| 4613 | + |
| 4614 | + // ordering LIST cardinality Date property |
| 4615 | + Supplier<GraphTraversal<?, Vertex>> tListDateFilter = () -> g.V().has("gender", "female").has("birth2").order().by("birth2", ORDER_DESC); |
| 4616 | + assertTraversalAndIndexUsage( |
| 4617 | + Arrays.asList( |
| 4618 | + "_condition=(gender = female AND birth2 <> null)", |
| 4619 | + "_query=[(gender = female AND birth2 <> null)][DESC(birth2)]:listPropertyOrdering" |
| 4620 | + ), |
| 4621 | + tListDateFilter, v6, v4, v2 |
| 4622 | + ); |
| 4623 | + } |
| 4624 | + } |
4437 | 4625 | } |
0 commit comments