|
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() { |
@@ -4754,4 +4757,189 @@ public void testGetIndexInfo() throws DecoderException { |
4754 | 4757 | assertEquals(1, indexInfo.getCompositeIndexType().getInlineFieldKeys().length); |
4755 | 4758 | assertEquals("id", indexInfo.getCompositeIndexType().getInlineFieldKeys()[0]); |
4756 | 4759 | } |
| 4760 | + |
| 4761 | + @Test |
| 4762 | + public void testOrderingListProperty() { |
| 4763 | + PropertyKey name1 = mgmt.makePropertyKey("name1").dataType(String.class).cardinality(Cardinality.SINGLE) |
| 4764 | + .make(); |
| 4765 | + PropertyKey name2 = mgmt.makePropertyKey("name2").dataType(String.class).cardinality(Cardinality.LIST) |
| 4766 | + .make(); |
| 4767 | + PropertyKey gender = mgmt.makePropertyKey("gender").dataType(String.class).cardinality(Cardinality.SINGLE).make(); |
| 4768 | + PropertyKey age1 = mgmt.makePropertyKey("age1").dataType(Double.class).cardinality(Cardinality.SINGLE).make(); |
| 4769 | + PropertyKey age2 = mgmt.makePropertyKey("age2").dataType(Double.class).cardinality(Cardinality.LIST).make(); |
| 4770 | + PropertyKey birth1 = mgmt.makePropertyKey("birth1").dataType(Date.class).cardinality(Cardinality.SINGLE).make(); |
| 4771 | + PropertyKey birth2 = mgmt.makePropertyKey("birth2").dataType(Date.class).cardinality(Cardinality.LIST).make(); |
| 4772 | + |
| 4773 | + mgmt.buildIndex("listPropertyOrdering", Vertex.class) |
| 4774 | + .addKey(name1, Mapping.STRING.asParameter()) |
| 4775 | + .addKey(name2, Mapping.STRING.asParameter()) |
| 4776 | + .addKey(gender, Mapping.STRING.asParameter()) |
| 4777 | + .addKey(age1) |
| 4778 | + .addKey(age2) |
| 4779 | + .addKey(birth1) |
| 4780 | + .addKey(birth2) |
| 4781 | + .buildMixedIndex(INDEX); |
| 4782 | + finishSchema(); |
| 4783 | + |
| 4784 | + 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"); |
| 4785 | + 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"); |
| 4786 | + 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"); |
| 4787 | + 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"); |
| 4788 | + 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"); |
| 4789 | + 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"); |
| 4790 | + tx.commit(); |
| 4791 | + |
| 4792 | + clopen(option(FORCE_INDEX_USAGE), false); |
| 4793 | + |
| 4794 | + final GraphTraversalSource g = tx.traversal(); |
| 4795 | + org.apache.tinkerpop.gremlin.process.traversal.Order ORDER_DESC = org.apache.tinkerpop.gremlin.process.traversal.Order.desc; |
| 4796 | + |
| 4797 | + // ordering without using index on SINGLE cardinality property |
| 4798 | + Supplier<GraphTraversal<?, Vertex>> tFullscanSingle = () -> g.V().order().by("name1"); |
| 4799 | + assertTraversalAndIndexUsage( |
| 4800 | + Arrays.asList( |
| 4801 | + "query=[]", |
| 4802 | + "_fullscan=true" |
| 4803 | + ), |
| 4804 | + tFullscanSingle, v1, v2, v3, v4, v5, v6 |
| 4805 | + ); |
| 4806 | + |
| 4807 | + // ordering without using index on LIST cardinality property with multiple values |
| 4808 | + // throws IllegalStateException with message "Multiple properties exist for the provided key, use Vertex.properties(name2)" |
| 4809 | + Exception exception = assertThrows(IllegalStateException.class, () -> { |
| 4810 | + g.V().order().by("name2").toList(); |
| 4811 | + }); |
| 4812 | + assertTrue(exception.getMessage().contains("Multiple properties exist for the provided key, use Vertex.properties(name2)")); |
| 4813 | + |
| 4814 | + /////////////////////////////////////////////////// |
| 4815 | + // ordering SINGLE cardinality properties |
| 4816 | + // ordering SINGLE cardinality String property |
| 4817 | + Supplier<GraphTraversal<?, Vertex>> tSingleString = () -> g.V().has("name1").order().by("name1", ORDER_DESC); |
| 4818 | + assertTraversalAndIndexUsage( |
| 4819 | + Arrays.asList( |
| 4820 | + "_condition=(name1 <> null)", |
| 4821 | + "_query=[(name1 <> null)][DESC(name1)]:listPropertyOrdering" |
| 4822 | + ), |
| 4823 | + tSingleString, v6, v5, v4, v3, v2, v1 |
| 4824 | + ); |
| 4825 | + |
| 4826 | + // ordering SINGLE cardinality Double property |
| 4827 | + Supplier<GraphTraversal<?, Vertex>> tSingleDouble = () -> g.V().has("age1").order().by("age1", ORDER_DESC); |
| 4828 | + assertTraversalAndIndexUsage( |
| 4829 | + Arrays.asList( |
| 4830 | + "_condition=(age1 <> null)", |
| 4831 | + "_query=[(age1 <> null)][DESC(age1)]:listPropertyOrdering" |
| 4832 | + ), |
| 4833 | + tSingleDouble, v6, v5, v4, v3, v2, v1 |
| 4834 | + ); |
| 4835 | + |
| 4836 | + // ordering SINGLE cardinality Date property |
| 4837 | + Supplier<GraphTraversal<?, Vertex>> tSingleDate = () -> g.V().has("birth1").order().by("birth1", ORDER_DESC); |
| 4838 | + assertTraversalAndIndexUsage( |
| 4839 | + Arrays.asList( |
| 4840 | + "_condition=(birth1 <> null)", |
| 4841 | + "_query=[(birth1 <> null)][DESC(birth1)]:listPropertyOrdering" |
| 4842 | + ), |
| 4843 | + tSingleDate, v6, v5, v4, v3, v2, v1 |
| 4844 | + ); |
| 4845 | + |
| 4846 | + ///////////////////////////////////////////////// |
| 4847 | + // ordering SINGLE cardinality properties with filtering |
| 4848 | + // ordering SINGLE cardinality String property |
| 4849 | + Supplier<GraphTraversal<?, Vertex>> tSingleStringFilter = () -> g.V().has("gender", "female").has("name1").order().by("name1", ORDER_DESC); |
| 4850 | + assertTraversalAndIndexUsage( |
| 4851 | + Arrays.asList( |
| 4852 | + "_condition=(gender = female AND name1 <> null)", |
| 4853 | + "_query=[(gender = female AND name1 <> null)][DESC(name1)]:listPropertyOrdering" |
| 4854 | + ), |
| 4855 | + tSingleStringFilter, v6, v4, v2 |
| 4856 | + ); |
| 4857 | + |
| 4858 | + // ordering SINGLE cardinality Double property |
| 4859 | + Supplier<GraphTraversal<?, Vertex>> tSingleDoubleFilter = () -> g.V().has("gender", "female").has("age1").order().by("age1", ORDER_DESC); |
| 4860 | + assertTraversalAndIndexUsage( |
| 4861 | + Arrays.asList( |
| 4862 | + "_condition=(gender = female AND age1 <> null)", |
| 4863 | + "_query=[(gender = female AND age1 <> null)][DESC(age1)]:listPropertyOrdering" |
| 4864 | + ), |
| 4865 | + tSingleDoubleFilter, v6, v4, v2 |
| 4866 | + ); |
| 4867 | + |
| 4868 | + // ordering SINGLE cardinality Date property |
| 4869 | + Supplier<GraphTraversal<?, Vertex>> tSingleDateFilter = () -> g.V().has("gender", "female").has("birth1").order().by("birth1", ORDER_DESC); |
| 4870 | + assertTraversalAndIndexUsage( |
| 4871 | + Arrays.asList( |
| 4872 | + "_condition=(gender = female AND birth1 <> null)", |
| 4873 | + "_query=[(gender = female AND birth1 <> null)][DESC(birth1)]:listPropertyOrdering" |
| 4874 | + ), |
| 4875 | + tSingleDateFilter, v6, v4, v2 |
| 4876 | + ); |
| 4877 | + |
| 4878 | + // certain mixed index backend specific part since Lucene does not support ordering for list properties |
| 4879 | + if (supportsOrderingListProperty) { |
| 4880 | + /////////////////////////////////////////////////// |
| 4881 | + // ordering LIST cardinality properties |
| 4882 | + // ordering LIST cardinality String property |
| 4883 | + Supplier<GraphTraversal<?, Vertex>> tListString = () -> g.V().has("name2").order().by("name2", ORDER_DESC); |
| 4884 | + assertTraversalAndIndexUsage( |
| 4885 | + Arrays.asList( |
| 4886 | + "_condition=(name2 <> null)", |
| 4887 | + "_query=[(name2 <> null)][DESC(name2)]:listPropertyOrdering" |
| 4888 | + ), |
| 4889 | + tListString, v3, v4, v6, v5, v2, v1 |
| 4890 | + ); |
| 4891 | + |
| 4892 | + // ordering LIST cardinality Double property |
| 4893 | + Supplier<GraphTraversal<?, Vertex>> tListDouble = () -> g.V().has("age2").order().by("age2", ORDER_DESC); |
| 4894 | + assertTraversalAndIndexUsage( |
| 4895 | + Arrays.asList( |
| 4896 | + "_condition=(age2 <> null)", |
| 4897 | + "_query=[(age2 <> null)][DESC(age2)]:listPropertyOrdering" |
| 4898 | + ), |
| 4899 | + tListDouble, v6, v5, v4, v3, v2, v1 |
| 4900 | + ); |
| 4901 | + |
| 4902 | + // ordering LIST cardinality Date property |
| 4903 | + Supplier<GraphTraversal<?, Vertex>> tListDate = () -> g.V().has("birth2").order().by("birth2", ORDER_DESC); |
| 4904 | + assertTraversalAndIndexUsage( |
| 4905 | + Arrays.asList( |
| 4906 | + "_condition=(birth2 <> null)", |
| 4907 | + "_query=[(birth2 <> null)][DESC(birth2)]:listPropertyOrdering" |
| 4908 | + ), |
| 4909 | + tListDate, v6, v5, v4, v3, v2, v1 |
| 4910 | + ); |
| 4911 | + |
| 4912 | + ///////////////////////////////////////////////// |
| 4913 | + // ordering LIST cardinality properties with filtering |
| 4914 | + // ordering LIST cardinality String property |
| 4915 | + Supplier<GraphTraversal<?, Vertex>> tListStringFilter = () -> g.V().has("gender", "female").has("name2").order().by("name2", ORDER_DESC); |
| 4916 | + assertTraversalAndIndexUsage( |
| 4917 | + Arrays.asList( |
| 4918 | + "_condition=(gender = female AND name2 <> null)", |
| 4919 | + "_query=[(gender = female AND name2 <> null)][DESC(name2)]:listPropertyOrdering" |
| 4920 | + ), |
| 4921 | + tListStringFilter, v4, v6, v2 |
| 4922 | + ); |
| 4923 | + |
| 4924 | + // ordering LIST cardinality Double property |
| 4925 | + Supplier<GraphTraversal<?, Vertex>> tListDoubleFilter = () -> g.V().has("gender", "female").has("age2").order().by("age2", ORDER_DESC); |
| 4926 | + assertTraversalAndIndexUsage( |
| 4927 | + Arrays.asList( |
| 4928 | + "_condition=(gender = female AND age2 <> null)", |
| 4929 | + "_query=[(gender = female AND age2 <> null)][DESC(age2)]:listPropertyOrdering" |
| 4930 | + ), |
| 4931 | + tListDoubleFilter, v6, v4, v2 |
| 4932 | + ); |
| 4933 | + |
| 4934 | + // ordering LIST cardinality Date property |
| 4935 | + Supplier<GraphTraversal<?, Vertex>> tListDateFilter = () -> g.V().has("gender", "female").has("birth2").order().by("birth2", ORDER_DESC); |
| 4936 | + assertTraversalAndIndexUsage( |
| 4937 | + Arrays.asList( |
| 4938 | + "_condition=(gender = female AND birth2 <> null)", |
| 4939 | + "_query=[(gender = female AND birth2 <> null)][DESC(birth2)]:listPropertyOrdering" |
| 4940 | + ), |
| 4941 | + tListDateFilter, v6, v4, v2 |
| 4942 | + ); |
| 4943 | + } |
| 4944 | + } |
4757 | 4945 | } |
0 commit comments